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 08/07/2025 15:19 | #
j'ai essayé avant et après Gint::Gint mais l'erreur n'a pas changé.
tu pourras pas utiliser ncurses avec gint sauf à coder un émulateur de terminal assez balèze
Citer : Posté le 08/07/2025 16:06 | #
Gint::Gint -lncursesw non ? Ou mets le .a directement.
Citer : Posté le 26/08/2025 00:17 | #
Je fais juste un petit passage pour saluer l'équipe du projet et de la bible SuperH de PC.
Le travail fait sur cette librairie et le reverse-engineering de l'archi de ces calculatrices est impressionnant. Naviguer au travers des pages de vos recherches m'ont happé et retenu mon intérêt pendant un bon moment. J'ai eu le dos tourné pendant quelques années et quand je me retourne, je vois que c'est le jour et la nuit comparé aux prémices avec les SDKs de Cemetech et autre.
Ça a été un plaisir de bricoler dans mon coin avec gint pour porter un certain jeu, que ce soit du côté code de bas niveau, la facilité de bricolage de la lib ou tout le framework de compilation pour faciliter l'intégration d'assets. C'est très propre, ça tourne bien et y'a même la possibilité de lancer et debugger depuis WSL? Chapeau bas, vraiment.
Je souhaite que ça se passe pour le mieux pour vous dans le futur. Bon courage pour la suite.
Citer : Posté le 26/08/2025 00:31 | #
Yo, Eiyeron, venant de toi les compliments touchent 10 fois plus. Rien de tout ça n'aurait existé sous cette forme sans les folies de ton époque et notamment les projets de Kristaba. Perso j'ai appris plein de trucs grâce à vous. C'est vraiment la boucle qui se boucle.
Les shaders pour les images dans le système de rendu fragmenté c'est vraiment ma pièce maîtresse. J'ai passé genre un mois et demi à optimiser le code assembleur. J'ai pas clairement discerné si t'as utilisé le rendu VRAM classique ou le pipeline fragmenté d'Azur, mais les perfs sont encore meilleures avec le deuxième. Je me mets à OpenGL récemment et ouais l'inspiration est clairement là...
Je suis curieux de voir ce que tu as tenté de modifier ou refaire dans gint. Si tu es parti de zéro, ça a dû être un sacré défi.
Pour la bible, Yatis a beaucoup contribué. Il se peut qu'une fois on ait passé pas loin de 25 heures en visio sur une semaine à décompiler le système de fichiers... c'est vraiment fun.
Love <3
Citer : Posté le 26/08/2025 01:00 | # |
Fichier joint
Ca me touche tout autant de t'entendre dire ça sur Kris et moi. Merci.
Concernant gint, oui, je me sers du rendu pipeliné de gint. C'est clairement le jour et la nuit quand je compare avec les vieux DrawSprites. En passant, je me sers d'un gros bloc de RAM comme buffer pour les backgrounds pour ne pas avoir à décompresser à chaque frame, sauf pour un certain fond où je streame carrément les données. Je sais plus si je l'ai mappé sur l'ancien bloc de VRAM. Oh, tant pis.
(De mémoire, j'ai bricolé deux versions de RLE. Un pour compresser les données de tilemap pour les background statiques et un par ligne pour compresser le background à scrolling des avant-derniers niveaux et des crédits (c'était lui la raison des 9800KB de la V1). J'ai encore moyen de faire mieux mais il me faudrait tellement de temps pour finir tout ce que je veux faire que j'ai probablement pas assez d'attention et de temps dans toute une vie. On verra bien.)
Concernant ma tentative de faire ma propre sauce inspiré par gint, j'étais surtout mis au défi par ma propre personne de refaire la partie graphique à zéro, quitte à garder le reste du code de "plateforme" dans son jus. J'étais surtout inspiré par ton système de rendu pipeliné et l'écriture partielle de l'écran dans le buffer du DSP. Parce que j'avais aussi Another World en tête, je me suis demandé si il était possible de faire du rendu par slices de sprites, comme un blitter dessinant n pixels à la volée par commande.
J'avais en gros une liste de n slices ordonnées en RAM pour que chaque scanline ait au maximum m slices à dessiner. Rajoutez par dessus un léger tri pour ordonner les draws et j'avais quelque chose qui marchait déjà plus rapidement que le implémentations naïves d'autrefois. Ca marchait "pas trop mal" (55 FPS) jusqu'à que je note une perte de framerate assez violente à mesure que je devais rallonger cette liste, notamment pour dessiner le texte. Y'avait clairement un potentiel mais je maîtrise pas assez bien l'architecture pour en tirer quelque chose de durable. Donc j'ai mis de côté mon orgueil et je suis passé directement sous gint.
Je mets ci-joint les fichiers de "blit" que j'ai gardé dans le repo spécialement pour toi. Petit bonus: je me souviens d'avoir eu un large gain dans une boucle quand j'ai switché de types variés à juste uint32_t pour les fonctions slice_xxx. Cela est logique (moins d'opcodes pour transcoder les registres, gestion de l'extension du signe et autre) mais le gain m'a bien fait rire pendant quelques jours. J'imagine pas à quoi ressemblaient vos recherches, tiens!
Sinon, après que j'ai passé le tout sous gint, j'ai juste bricolé celui-ci pour forcer un rendu en 320x224, pour suivre la résolution originale du jeu, c'est l'une des clefs du framerate quasi-parfait: moins de pixels à traiter et à envoyer. Ensuite, j'avais essayé de fixer aussi l'écran de panic mais c'était un peu le cadet de mes soucis.
Faudrait que je revois la logique pour voir si il y a pas moyen de gratter un peu sur la logique gameplay du jeu mais même sans profiler je suis sur que 80% du temps de CPU c'est le rendu.
EDIT: j'ai oublié que j'écrivais pas dans le topic de BAM, j'ai juste changé pour faire d'un paragaphe quasi hors-sujet une parenthèse.
Citer : Posté le 26/08/2025 16:25 | #
Ok ok en fait t'as tenté de réimplémenter le pipeline de rendu. Légère confusion. Dans ma tête réimplémenter gint c'était genre tu réécris les drivers, interruptions, allocateur mémoire etc. Ça semblait gros. xD
Tous les shaders marchent comme ça avec Azur. Si une commande de dessin intersecte plusieurs fragments, le shader est invoqué une fois par fragment. Donc pour les images y'a un découpage automatique en bandes horizontales qui sont ensuite chacune considérées comme des commandes individuelles et triées par y croissant avant le rendu/streaming. C'est juste que les fragments font ~15 pixels de haut.
Ça passe pas super bien à l'échelle si y'a trop de commandes (générer les commandes finit par déclencher le bottleneck d'écriture en RAM que le pipeline de rendu est supposé contourner) ce qui veut dire qu'il faut écrire des shaders à la main pour tous les trucs un peu compliqués. Ça demande des efforts mais généralement ça paie.
Le compilo est pas très prévisible à ce niveau donc la plupart de mon code est en assembleur, pipeliné/super-scalarisé à la main. C'est un régal parce que les temps d'écriture dans la mémoire on-chip sont très prévisibles du coup tu peux descendre un corps interne de boucle de genre 6 cycles à 5 cycles et tu vois le runtime diminuer de 17%. C'est génial x) Une fois j'ai rajouté un nop et j'ai gagné 15% de vitesse parce que alignement (et ça le compilo il le fait pas).
Mais donc je vois que t'as suivi les mêmes idées que moi ! (Les grands esprits se rencontrent lol.)
Oui. C'est toujours le rendu x)
Toi qui fais plus de graphismes que le reste d'entre nous mortels (ou l'immense majorité en tous cas), si tu veux jouer un peu plus tu sais à quelle porte toquer.
Citer : Posté le 28/08/2025 01:22 | #
Hello !
Je cherche un moyen de lister tout les fichiers d'un répertoire et aussi de savoir si un répertoire (dossier) existe, avec gint.
Parce qu'avec std::filesystem ça ne compile pas.
Albert Einstein
Citer : Posté le 28/08/2025 01:34 | #
Faut se rabattre sur <dirent.h>. std::filesystem c'est super super moderne...
Edit : et pour l'existence, stat().
Citer : Posté le 28/08/2025 05:04 | #
Merci !
Et avec gint est-ce qu'il y a une fonction qui permet de récupérer les input texte ? Genre "7" -> M
Il me semble qu'elle existe mais je n'arrive pas un la retrouver
Albert Einstein
Citer : Posté le 28/08/2025 07:54 | #
Tu as rien de plus que les fonctions *scanf() du C.
C'est implémenté depuis la 2.9 ou 2.10 je crois.
Après le traitement c'est pour toi à la main
j'ai jamais trop regardé du côté de <iostream>, je pense que certains trucs doivent fonctionner, mais je ne sais pas dire quoi avec certitude.
Citer : Posté le 28/08/2025 09:13 | #
Non parce que ça dépend de trop de choix d'UI. Mais tu peux piquer tout le code que tu veux dans JustUI : https://git.planet-casio.com/Lephenixnoir/JustUI/src/branch/master/src/jinput.c
Citer : Posté le 28/08/2025 14:32 | #
Okay !
Je pensais qu'il y avait déjà une fonction intégré dans gint mais non. D'ac merci !
Albert Einstein