gint : un noyau pour développer des add-ins
Posté le 20/02/2015 17:30
Ce topic fait partie de la série de topics du fxSDK.
En plus des options de programmation intégrée comme le Basic Casio ou Python, la plupart des calculatrices Casio supportent des
add-ins, des programmes natifs très polyvalents avec d'excellentes performances. Les add-ins sont généralement programmés en C/C++ avec l'aide d'un ensemble d'outils appelé SDK.
Plusieurs SDK ont été utilisés par la communauté avec le temps. D'abord le
fx-9860G SDK de Casio avec fxlib pour Graph monochromes (plus maintenu depuis longtemps). Puis le
PrizmSDK avec libfxcg pour Prizm et Graph 90+E (encore un peu actif sur Cemetech). Et plus récemment celui que je maintiens, le
fxSDK, dont gint est le composant principal.
gint est un unikernel, ce qui veut dire qu'il embarque essentiellement un OS indépendant dans les add-ins au lieu d'utiliser les fonctions de l'OS de Casio. Ça lui permet beaucoup de finesse sur le contrôle du matériel, notamment la mémoire, le clavier, l'écran et les horloges ; mais aussi de meilleures performances sur le dessin, les drivers et la gestion des interruptions, plus des choses entièrement nouvelles comme le moteur de gris sur Graph monochromes.
Les sources de gint sont sur la forge de Planète Casio :
dépôt Gitea Lephenixnoir/gint
Aperçu des fonctionnalités
Les fonctionnalités phares de gint (avec le fxSDK) incluent :
- Toutes vos images et polices converties automatiquement depuis le PNG, sans code à copier (via fxconv)
- Un contrôle détaillé du clavier, avec un GetKey() personnalisable et un système d'événements à la SDL
- Une bibliothèque standard C plus fournie que celle de Casio (voir fxlibc), et la majorité de la bibliothèque C++
- Plein de raccourcis pratiques, comme pour afficher la valeur d'une variable : dprint(1,1,"x=%d",x)
- Des fonctions de dessin, d'images et de texte optimisées à la main et super rapides, surtout sur Graph 90+E
- Des timers très précis (60 ns / 30 µs selon les cas, au lieu des 25 ms de l'OS), indispensables pour les jeux
- Captures d'écran et capture vidéo des add-ins par USB, en temps réel (via fxlink)
Avec quelques mentions spéciales sur les Graph monochromes :
Un moteur de gris pour faire des jeux en 4 couleurs !
La compatibilité SH3, SH4 et Graph 35+E II, avec un seul fichier g1a
Une API Unix/POSIX et standard C pour accéder au système de fichiers (Graph 35+E II seulement)
Et quelques mentions spéciales sur les Graph 90+E :
Une nouvelle police de texte, plus lisible et économe en espace
Le dessin en plein écran, sans les bordures blanches et la barre de statut !
Un driver écran capable de triple-buffering
Une API Unix/POSIX et standard C pour accéder au système de fichiers
Galerie d'add-ins et de photos
Voici quelques photos et add-ins réalisés avec gint au cours des années !
Arena (2016) — Plague (2021)
Rogue Life (2021)
Momento (2021)
Communication avec le PC (cliquez pour agrandir)
Utiliser gint pour développer des add-ins
Les instructions pour installer et utiliser gint sont données dans les divers tutoriels recensés dans le
topic du fxSDK. Il y a différentes méthodes de la plus automatique (GiteaPC) à la plus manuelle (compilation/installation de chaque dépôt). Le fxSDK est compatible avec Linux, Mac OS, et marche aussi sous Windows avec l'aide de WSL, donc normalement tout le monde est couvert
Notez en particulier qu'il y a des
tutoriels de développement qui couvrent les bases ; tout le reste est expliqué dans les en-têtes (fichiers
.h) de la bibliothèque que vous pouvez
consulter en ligne, ou dans les ajouts aux changelogs ci-dessous.
Changelog et informations techniques
Pour tester les fonctionnalités et la compatibilité de gint, j'utilise un add-in de test appelé gintctl (
dépôt Gitea Lephenixnoir/gintctl). Il contient aussi une poignée d'utilitaires d'ordre général.
Ci-dessous se trouve la liste des posts indiquant les nouvelles versions de gint, et des liens vers des instructions/tutoriels supplémentaires qui accompagnent ces versions.
Anecdotes et bugs pétés
Ô amateurs de bas niveau, j'espère que vous ne tomberez pas dans les mêmes pièges que moi.
TODO list pour les prochaines versions (2023-04-03)
gint 2.11
- Changements de contextes CPU. À reprendre du prototype de threading de Yatis pour permettre l'implémentation d'un véritable ordonnanceur. Demandé par si pour faire du threading Java.
- Applications USB. Ajouter le support de descripteurs de fichiers USB. Potentiellement pousser jusqu'à avoir GDB pour debugger.
- Support de scanf() dans la fxlibc. Codé par SlyVTT, plus qu'à nettoyer et fusionner.
Non classé
- Regarder du côté serial (plus facile que l'USB) pour la communication inter-calculatrices (multijoueur) et ultimement l'audio (libsnd de TSWilliamson).
- Un système pour recompiler des add-ins mono sur la Graph 90+E avec une adaptation automatique.
- Support des fichiers en RAM pour pouvoir utiliser l'API haut-niveau sur tous les modèles et éviter la lenteur de BFile à l'écriture quand on a assez de RAM.
Citer : Posté le 15/07/2020 10:09 | # | Fichier joint
The command-line looks normal - "fxconv --bopti-image assets-fx/img/Untitled.png -o build-fx/assets/img/Untitled.png.o --fx --toolchain=sh-elf name:img_Untitled" (Untitled.png is the test image)
Ajouté le 15/07/2020 à 10:42 :
Looks like it only happens when you have too many transparent pixels?
Ajouté le 15/07/2020 à 11:25 :
I've been experimenting with it and it's really inconsistent. A fully transparent image will be drawn fine, but put a few black pixels in and the whole thing turns black. Some other sprites have no problems with transparency. This is on the latest commit of the dev branch. dtext and dprint also appears to be broken, when I build the default addin it hangs the calc
Citer : Posté le 15/07/2020 12:25 | #
Okay, I'll check that ASAP. The prototypes of dtext() and dprint() have been updated but I only pushed the new default program a few days later so I believe it's unrelated. My first thoughts is the quantification process used in fxconv, I'll keep you up-to-date.
Citer : Posté le 15/07/2020 14:07 | #
Big problem. I switched back to the master branch and I'm still getting the bugs - text still won't show, even though it worked fine before on the master branch and I definitely rebuilt gint. Same with the transparency.
At this point I think it might be a problem on my end, but I don't see what it could be. I rebuilt gint and fxSDK, and the fx9860g.ld and libgint-fx.a files were copied over, as well as all the includes.
I can rebuild the whole toolchain again tomorrow if I have to, it'd just be a bit tedious.
Citer : Posté le 15/07/2020 19:14 | #
I don't think the toolchain is at fault here, don't bother rebuilding it for now. When switching to the master branch, you need to be careful to install a corresponding version of the fxSDK, especially because fxconv changed a few times since then. I try to keep the repos tidy but to be entirely honest it's pretty hard to bisect things currently. ^^"
If you can, let's try to debug things out of the latest branches to eliminate a potential source of bugs.
I can't reproduce it right now. I've tried several images including the sprite from your previous post (or at least something close to it since I had to guess the transparent parts), but they seem to work.
Have you rebuilt the whole project each time you changed the library or fxSDK version (make -B)? If so, could you provide a buggy image and try it in a new fxSDK/gint project on the latest commit?
Citer : Posté le 16/07/2020 00:44 | # | Fichier joint
I got text working again (not sure how, switching back to dev seemed to do something), but still have the buggy sprites. I'll attach a zip file with a test project including the buggy sprite, g1a, and example screenshot. All of this is on the latest branches.
I guess I'll just have to use opaque sprites for now and hope nothing has to overlap
Ajouté le 16/07/2020 à 13:06 :
Maybe if you built the test addin, verified the transparency works fine with you, then compared the two player.png.o files we could see if it's fxconv or my image editor that's faulty since they should be the same
Citer : Posté le 16/07/2020 15:37 | #
I can reproduce. It works fine if the image is not indexed. I think this is due to the way I extract the alpha channel to first make every pixel either opaque or transparent. In indexed images, there might not be an alpha channel.
Ajouté le 16/07/2020 à 15:43 :
Added a preliminary conversion of indexed images to RGBA format to make the alpha channel appear in fxconv's quantize() function. This solved the problem on your example, so the image should work. See 66d88be.
I suppose the inconsistencies you found were related to how your image editing software and the Pillow library encoded/decoded the palette based on the available pixels.
Citer : Posté le 16/07/2020 16:27 | #
It does not surprise me, I found the bug working on a personnal project. It is not so common to use indexed colors, so I exported the images in RGB8 mode.
Glad to see you fixed the bug anyway
Citer : Posté le 16/07/2020 16:49 | #
I was using paint.net to edit the images, and I'm pretty sure it was saving them as 24-bit indexed automatically. I manually changed the bit depth to 32 and it solved the problem, though I'm glad indexed images can be processed now.
Back to my project I guess, really happy we could figure this out
Citer : Posté le 16/07/2020 17:01 | #
You're welcome! I'm happy that my tools are growing more stable and versatile by the day.
Citer : Posté le 17/07/2020 20:30 | # | Fichier joint
Comme il me manquait les tests pour la RTC dans gintctl pour valider l'histoire du spread spectrum, j'en ai profité pour faire l'horloge qui manquait depuis un bon moment. Ça viendra remplacer mon Horloge SH4 ultimement, parce que c'est quand même mieux foutu.
Elle marche aussi sur Graph 90 bien sûr, c'est juste très lent de manipuler la Graph 90 (temps de transfert élevé et temps de sauvegarde du screen élevé) donc j'ai pris la mono.
Ajouté le 17/07/2020 à 20:43 :
Pendant que j'y suis j'ai refait le test sur la vitesse de traitement des interruptions. Le setup est simple, on demande 1 million d'interruptions par seconde et on regarde combien on arrive à en caser.
Sur la Graph mono sans overclock, gint traite environ 110'000 interruptions par seconde. Ça a un peu baissé surtout depuis que j'ai renforcé la sécurité de la chose lorsqu'on fait des callbacks, mais ça reste pas mal.
Sur la Graph 90 sans overclock, comme le processeur est cadencé plus haut de base, ça donne un peu plus de 300'000 interruptions par seconde. Et en poussant l'overclock, on arrive à en obtenir 550'000. Ça veut dire qu'un timer trivial peut être exécuté toutes les 2 µs si ça nous chante ! xD
Ajouté le 20/07/2020 à 21:01 :
Bien donc ces derniers jours j'ai fait d'autres améliorations discrètes : j'ai ajouté la gestion du spread spectrum sur Graph 90 (une broutille qui permet de corriger les estimations de fréquence des timers entre autres) et j'ai ajouté une fonction gint_setrestart() qui remplace la fin de l'add-in par un appel à gint_osmenu() pour qu'on puisse retourner dans l'add-in après la fin de main(), avec cependant les quelques contraintes inhérentes à gint_osmenu().
Ce qui est important c'est que gint rentre maintenant en phase de release. Je vais très rapidement publier les commits qui suppriment les fonctionnalités qui doivent disparaître avec la v2.1 (par exemple image_t a été renommé en bopti_image_t mais l'alias a été laissé, je vais maintenant le supprimer).
Après ces modifications on sera sur le premier release candidate, une sorte de bêta de dernière instance pour les tous derniers bugs à corriger avant la release. Vous pouvez voir ça comme gint v2.1, celui que je hype depuis des mois. :3
Je vais passer quelques temps hors de l'ajout de fonctionnalité (mais je corrigerai toujours les bugs) pour réécrire les topics, continuer les tutoriels, faire de la documentation, et parler un peu du projet à quelques endroits où je ne l'ai pas encore fait.
Je vous en dirait plus au fur et à mesure dans les RDP ou sur ce topic. Merci à toutes les personnes qui utilisent gint, j'espère que la toute nouvelle version vous sera encore plus utile. o/
Citer : Posté le 21/07/2020 09:35 | #
A quand un séance de présentation de tout ce travail au DevFest ? Honnêtement je suis sûr que tu pourrais trouver ta place dans ce genre d'événement pour y présenter le développement sur Casio moderne avec gint .
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)
Citer : Posté le 21/07/2020 09:42 | #
Ha ha merci ! Je doute que ça intéresse vraiment, pour être honnête. Mais c'est gentil de l'avoir imaginé
Citer : Posté le 21/07/2020 10:31 | #
J'ai assisté à une conférence sur comment faire de la musique avec des lignes de codes, ce que je veux dire c'est qu'il y a pas mal de trucs de hypster informaticien, je pense que montrer qu'on peut faire des jeux en niveau de gris sur monochrome pourrait être intéressant, genre un truc rapide de 30 minutes où tu présenterais les démarche de reverse engineering et tout .
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)
Citer : Posté le 21/07/2020 10:33 | #
Je suis pas sûr qu'en 30 minutes t'arrive à présenter ne serait-ce que les démarches
Citer : Posté le 21/07/2020 10:35 | #
Non mais expliquer rapidement que t'as désassemblé le bazar, analysé chaque morceau avec une communauté de geeks, puis recréé une librairie plus puissante que ce qu'on espérait, puis là tu montre des exemple de ce qui est faisable .
Pourras-tu survivre plus de 20 secondes dans ce fameux tunnel appelé Graviton
Rebondis entre les murs en évitant les piques dans SpikeBird
Pourras-tu éviter de te faire écraser dans FallBlocs (élu Jeu Du Mois)
La version 2048 tactile amélioré au plus haut point : 2048 Delux !
Pars à la recherche des morceaux d'étoile dans Lumyce (élu Jeu Du Mois)
Citer : Posté le 21/08/2020 17:43 | #
Puisque personne n'a fait remonter de bug sur le release candidate de la version 2.1 de gint (possiblement parce que presque personne ne code en ce moment), j'ai poussé les tags... et mis à jour la branche master, ce qui est constitue une release officielle d'une nouvelle version majeure de gint.
On ne dirait pas comme ça, mais ça fait maintenant plus de 5 ans que cette idée a commencé, et ça fait immensément plaisir de voir que non seulement le code tient toujours et marche après tout ce temps, mais qu'en plus c'est utilisé par des vrais projets. Merci beaucoup pour votre soutien ! <3
Avec la release de gint 2, quasiment tous les modèles qu'on croise régulièrement sont supportés !
• Les vieilles Graph 35+ (blanches) SH3 sont supportées ;
• Les Graph 35+ (blanches), 35+ USB, 35+E, 35+E II sont supportées ;
• Les Graph 75, 75+, 75+E sont supportées ;
• Les Prizm, fx-CG 20, Graph 90+E et fx-CG 50 sont supportées ;
• L'émulateur Graph 35+E II et l'émulateur fx-CG 50/Graph 90+E sont supportés.
Les modèles qui restent (Graph 85, 95 SD, fx-CG 10) n'ont jamais été testés, si vous en avez un je suis preneur. Il reste les ClassPad dont le format est très différent et qui ne sont pas du tout supportés.
Bien sûr, tout cela va avec les fonctionnalités importantes qui ont été ajoutées depuis le première release, et qui ont complètement transformé gint en un outil bien supérieur. Il y en a trop pour toutes les citer, mais on peut notamment penser au retour au menu et système de fichiers stables, à l'ajout du TLB dynamique (pour les add-ins de grande taille) et du DMA (pour l'écran de la Graph 90+E), et au modèle du clavier qui unifie getkey() et keydown() comme jamais avant.
Bien sûr il reste plein de choses qu'on peut ajouter, mais pour l'instant je voudrais me concentrer sur la documentation et les tutoriels de gint, et coder aussi des jeux pour moi parce que ça fait un moment que j'écris quasiment plus que du code noyau !
J'ai d'ailleurs publié aujourd'hui quelque chose d'un peu nouveau sur les tutoriels d'utilisation de gint. J'ai repris le tutoriel existant et l'ai étendu en modifiant le concept du jeu pour simplifier le développement et la rédaction, puis j'ai publié une deuxième partie. Ça fait un moment que je garde tout ça au chaud. Les nouveaux tutoriels prennent plus le temps d'expliquer le fonctionnement de gint et du fxSDK pour vous armer face aux problèmes communs. Jetez-y un oeil !
Nouvelle version majeure : gint 2.1.0
Nouvelles fonctionnalités (depuis la dernière bêta) :
• Support des polices Unicode. [#177494]
• Ajouté des fonctions pour distinguer les touches F1..F6 et 0..9 dans <gint/keyboard.h>.
• Ajouté le contrôle du spread spectrum sur Graph 90+E (une technique de réduction de bruit électromagnétique mais qui change la fréquence des horloges)
• Ajouté une option pour revenir dans l'add-in après l'avoir quitté via gint_osmenu().
• Ajouté un filtre de répétitions à getkey_opt() pour contrôler finement les répétitions de toutes les touches.
Changements :
• Intégré l'API du moteur de gris dans le module de dessin. [#177478]
• Ajouté des valeurs par défaut raisonnable au moteur de gris sur tous les modèles.
• Modifié drastiquement le système de gestion d'interruptions sur SH3 et la méthode générale d'appel de callbacks pour supporter les interruptions successives et augmenter la stabilité sur tous les modèles.
• Étendu le timer RTC pour utiliser un format similaire au récent changement de timer_setup().
• Grosses améliorations de performances sur le dessin de petites images avec dsubimage() sur mono.
• Améliorations sur la vitesse de memcpy() et memset() à peu près partout.
Fonctionnalités supprimées :
• Supprimé l'alias image_t pour le type bopti_image_t.
• Supprimé les alias de fonctions g*() laissés après la modification de l'API du moteur de gris.
• Supprimé la branche compat du dépôt.
Citer : Posté le 22/08/2020 17:44 | #
Super tout ça ! Je mets à jour le paquet sur l'AUR dès que je rentre chez moi. Ça sera déployé chez tous les utilisateurs dans la foulée
Citer : Posté le 23/08/2020 08:43 | #
Bravo Lephenixnoir pour ce superbe travail ! Gint a l'air d'être un outil vraiment incroyable, qui mériterait d'être légèrement mis plus en avant, et qui j'espère permettra la conception d'excellent jeux.
Je rêverais apprendre à l'utiliser (mais maintenant je n'ai plus d'excuses avec l'accès à AUR, les tutoriels et la dernière version stable...).
Il est prévu d'entamer une nouvelle version ou tu fais une pause pour le moment ?
Citer : Posté le 23/08/2020 09:28 | #
Merci beaucoup ! Je vais faire un tour dans la RDP d'aujourd'hui et je ferai sans doute un article en page d'accueil un peu plus tard (quand il y aura de la place dans les publications).
Tu es au bon endroit !
Je n'ai pas du tout prévu de nouvelle version majeure ; le but c'est de rester le plus longtemps possible sur celle-ci, ce qui inclut aussi la stabilité de l'API (c'est-à-dire que quand une nouvelle version sort, en principe vous devez pouvoir recompiler les programmes sans les modifier).
Il y a des extensions prévues (DSP, accès à d'autres zones de RAM, communication série/USB si on y arrive...), mais ce qui existe ne devrait plus trop changer.
Dans tous les cas, je vais ralentir un peu l'évolution de gint et plutôt écrire des tutoriels et de la documentation ou coder des petits jeux. Je pense que je vais revisiter quelques-uns de mes programmes existants
Citer : Posté le 23/08/2020 18:30 | #
Le paquet AUR est à jour sur le commit 4288dc27d9. o/
Citer : Posté le 23/08/2020 18:51 | #
Yes, je me procure gint demain.