fxSDK, un SDK alternatif pour écrire des add-ins
Posté le 29/08/2014 22:00
Cette page sert d'index pour la série de topics du fxSDK.
Le fxSDK est une collection d'outils permettant de développer des add-ins pour les calculatrices Casio des séries Graph. C'est une alternative au
fx-9860G SDK et
PrizmSDK qui ne sont plus activement maintenus, et le compagnon classique de mon noyau
gint.
Index des topics
Ce projet existe depuis 2015, alors il y a pas mal de topics liés. En voici une liste complète !
Topics principaux
Installation du fxSDK
Tutoriels
Compatibilité sur calculatrice et PC
Côté PC, le fxSDK est compatible avec
Linux, Mac OS, et WSL pour Windows ; normalement tout le monde peut l'utiliser. Je teste constamment sous Linux, et WSL est un Linux donc c'est testé aussi. Je n'ai pas de Mac OS donc il peut y avoir quelques surprises, mais en général c'est l'affaire de corriger un bug ou deux.
En termes de calculatrices, le fxSDK supporte :
Calculatrices monochromes
- Graph 35+E II
- Graph 35+ USB / Graph 35+E (SH3/SH4)
- Graph 75/75+/75+E
- Graph 85/85 SD/95 (SD) (pas activement testé)
Calculatrices couleurs
- Graph 90+E / fx-CG 50
- Prizm fx-CG 10/20
Comment installer le fxSDK et coder des add-ins
Le fxSDK s'installe à partir de dépôts Git sur la
forge de Planète Casio (par exemple
Lephenixnoir/fxsdk). Il y en a un peu beaucoup, donc manuellement c'est assez long. Pour que ça aille plus vite et pour simplifier le travail des débutants, il y a un outil appelé
GiteaPC qui peut faire ça pour vous.
Si vous utilisez Windows, vous aurez besoin de WSL pour accéder à un système Linux dans Windows. Heureusement, Microsoft a fait ça bien et c'est facile à faire. Voyez le
tutoriel d'installation de WSL 2 (et l'explication rapide de
ce que WSL 2 est).
Si vous utilisez Mac OS, ouvrez l’œil en lisant les topics pour ne pas manquer les informations supplémentaires et éventuelles déviations par rapport à la procédure normale sous Linux.
Méthode automatique avec GiteaPC (plus rapide / recommandée pour les débutants)
- Suivez le tutoriel d'utilisation de GiteaPC, qui explique comment obtenir le fxSDK.
Méthode automatique avec plugin VS Code
- Yannis300307 a créé un plugin VS Code Casio Dev Tools qui fonctionne sous Windows (avec WSL) et Debian (probablement les dérivés aussi).
Méthode AUR pour les utilisateurs Arch/Manjaro/dérivés (ils se reconnaîtront)
- Dark Storm maintient MiddleArch, un dépôt de paquets précompilés qui a entre autres le fxSDK.
Méthode manuelle (plus fine / classique pour les habitués)
- Compilez et installez le cross-compilateur GCC pour SuperH.
- installez (dans cet ordre) les dépôts fxSDK, OpenLibm, fxlibc, gint ; en option, Slyvtt/µSTL_2.3.
Description sommaire du fxSDK
Pour une introduction à l'utilisation du fxSDK qui montre comment utiliser les outils pour développer un add-in, lisez plutôt les
tutoriels d'utilisation de gint. Cette section est juste une description sommaire.
Le cœur du fxSDK est un cross-compilateur GCC pour SuperH, habituellement nommé
sh-elf-gcc. Bien sûr on a avec toute la suite d'outils, dont
as,
ld,
objdump,
objcopy (entre autres). Contrairement au vieux compilateur du SDK, GCC est un compilateur moderne avec beaucoup d'options et capable de très solides optimisations.
Sur la calculatrice, c'est
le noyau gint qui fait la majorité du travail. Il remplace fxlib/libfxcg et une partie de l'OS pour vous offrir des fonctionnalités plus cool et plus rapides. Les add-ins développés avec le fxSDK utilisent gint toutes les trois lignes !
Il y a enfin plusieurs outils utiles sur le PC qui sont utilisés durant le développement ou l'utilisation des add-ins :
- fxsdk est un script shell qui permet de créer et compiler les projets sans se prendre trop la tête. Le système de compilation officiel pour les add-ins est CMake, mais un système plus ancien de Makefile est encore supporté.
- fxconv est un outil très polyvalent qui convertit à la compilation les assets (images, polices, maps....). Il permet de travailler avec des logiciels et formats de fichiers normaux sur le PC et d'avoir automatiquement un format optimisé sur la calculatrice. fxconv est extrêmement extensible et chaque projet peut ajouter des conversions personnalisées.
- fxgxa crée les fichiers g1a (format des add-ins pour Graph monochromes) et g3a (format des add-ins pour Graph couleurs) à partir des programmes compilés.
- fxlink est un outil de communication qui peut transférer des fichiers vers les Graph 35+E II et Graph 90+E en ligne de commande, mais aussi échanger interactivement avec les add-ins gint par le câble USB, et est couramment utilisé pour réaliser des captures d'écran ou captures vidéo des add-ins.
Changelog et informations techniques
Ci-dessous se trouve la liste des posts annonçant les nouvelles versions du fxSDK, ainsi que des liens vers les instructions/tutoriels supplémentaires publiés avec.
Citer : Posté le 20/11/2021 18:03 | #
Je ne vais pas mentir, des fois c'est aussi un filtre... c'est juste pas possible de développer en C avec un pied dans le bas-niveau si on n'arrive pas à maîtriser un peu le terminal, voir où sont les erreurs dans la sortie d'un programme, et d'autres trucs basiques du genre. Sauf qu'on peut pas dire ça quand les amateurs un poil trop optimistes posent des questions sans queue ni tête, parce que ça fait passer pour un con. :x
Citer : Posté le 20/11/2021 18:26 | #
Je ne vais pas mentir, des fois c'est aussi un filtre... c'est juste pas possible de développer en C avec un pied dans le bas-niveau si on n'arrive pas à maîtriser un peu le terminal, voir où sont les erreurs dans la sortie d'un programme, et d'autres trucs basiques du genre. Sauf qu'on peut pas dire ça quand les amateurs un poil trop optimistes posent des questions sans queue ni tête, parce que ça fait passer pour un con. :x
C'est hélas la dure expérience, souvent ça douche les espoirs... Mais coder c'est aussi se prendre la tête sur des bugs qu'on mets parfois des jours à comprendre (ou pas), parfois juste pour une ânerie.
Dis Lephe, j'ai maintenant bien stabilisé la base de mon jeu, et je voudrais implémenter un système de niveaux. Y'a-t-il un tuto sur la partie BFile de gint ? j'ai regardé le #include correspondant (gint/bfile.h) mais c'est light en documentation.
Si je comprends bien c'est seulement un accès en binaire en lecture/écriture donc rien du genre lecture/écriture de types prédéfinis (genre fprintf/fscanf).
Pourrais tu me dire où trouver du support (soit doc/tuto ou des sources à analyser) pour comprendre la partie interaction avec le filesystem.
Merci
Sly
Ajouté le 20/11/2021 à 18:45 :
Pourrais tu me dire où trouver du support (soit doc/tuto ou des sources à analyser) pour comprendre la partie interaction avec le filesystem.
Sly
Je down cette partie du topic, j'avais mal cherché, j'ai trouvé un vieux fil sur le topic Bfile. Je devrais pouvoir me débrouiller avec.
Citer : Posté le 20/11/2021 18:45 | #
L'include te dit à peu près tout pour être honnête. Est-ce qu'il y a quelque chose que tu ne comprends pas dans le mécanisme d'ouverture/lecture/écriture de fichiers de ce header ? Note que les noms de fichiers c'est juste u"\\\\fls0\\fichier.txt", sachant le que \\fls0\ désigne la mémoire de stockage et que le u"" est ce qui te donne une chaîne 16-bit (merci GCC, l'encodage est un peu ingrat sinon).
Il n'y a rien d'autre côté filesystem pour l'instant, mais KikooDX vient de me mettre un coup de fouet pour le faire et c'est en cours avec une API standard C (et un peu de l'API Unix en-dessous juste au cas où ça soit utile). Ce sera dans la limite de ce que la Graph 35+E II/90+E veut bien faire de façon standard (ie. allonger un fichier quand on écrit à la fin), mais a priori ce genre de problèmes est plutôt dans le passé (les vieilles versions un peu nulles du fs) et j'ai de bons espoirs que ça va marcher correctement.
Citer : Posté le 20/11/2021 18:58 | #
L'include te dit à peu près tout pour être honnête. Est-ce qu'il y a quelque chose que tu ne comprends pas dans le mécanisme d'ouverture/lecture/écriture de fichiers de ce header ? Note que les noms de fichiers c'est juste u"\\\\fls0\\fichier.txt", sachant le que \\fls0\ désigne la mémoire de stockage et que le u"" est ce qui te donne une chaîne 16-bit (merci GCC, l'encodage est un peu ingrat sinon).
.
Oui c'est exactement ça, je comprenais pas comment on choppait le file descriptor en passant un unsigned int * en parametre.
merci.
Citer : Posté le 27/12/2021 21:13 | #
Juste un message de service pour dire que Rogue Life, sur lequel j'arrive à avancer ces jours-ci, contient deux convertisseurs fxconv qui me semblent d'utilité générale :
J'espère à terme pouvoir distribuer les deux avec le fxSDK, surtout vu ce qu'on fait comme add-ins sur Planète Casio. Mais j'aimerais bien savoir avant si ça serait utile. Concrètement : est-ce que vous utiliseriez ces convertisseurs en supposant qu'ils soient disponibles nativement avec le fxSDK ?
Citer : Posté le 28/12/2021 09:26 | #
Concernant Tiled, je suis arrivé à bricoler des choses, et je crois que c'est le cas de pas mal de monde . À voir si ta version apporte une vraie plus-value par rapport à ce qu'on peut bricoler, ça peut être intéressant.
Pour Aseprite, avoir des animations directement encodée depuis fxconv ça doit être très agréable à manipuler ! Toujours la même question de savoir si le format des animations et ensuite simple à manipuler ?
De toute façon je te dirais de tout mettre en ligne, ceux qui veulent bricoler continueront de bricoler, ceux qui ne veulent pas perdre de temps là-dessus les utiliseront…
Citer : Posté le 28/12/2021 10:32 | #
Merci ! Le format des animations est une très bonne question, la plus importante à mon avis. Parce que les maps et les sprites sont complexes donc tout le monde ne veut pas forcément le même format. Si je l'implémente c'est certain qu'il y aura moyen d'obtenir les données brute en Python sans encodage particulier (pour que chacun fasse la structure qu'il veut), et potentiellement une version avec un format pré-définie.
Pour donner une idée, actuellement le convertisseur Aseprite prend une image comme ça (prise du topic Rogue Life) :
Il récupère les animations marquées par les tags (qui contient aussi les durées, ce qui est pratique parce que du coup ce qu'on voit dans Aseprite est vraiment ce qu'on voit à l'écran) :
Skipped 0x2007
player_down.aseprite (24x24) has 4 animations:
'Idle': Frames 0 to 1 (800 ms, 800 ms)
'Walking': Frames 2 to 5 (150 ms, 150 ms, 150 ms, 150 ms)
'Hit': Frames 6 to 9 (50 ms, 50 ms, 200 ms, 200 ms)
'Attack': Frames 10 to 12 (100 ms, 50 ms, 200 ms)
Ensuite il forme une spritesheet et chaque frame est une structure de ce style :
{
/* Sheet */
bopti_image_t const *sheet;
/* Box for the frame within the sheet */
uint8_t x, y, w, h;
/* Position of center for this frame */
int8_t cx, cy;
/* Duration of the frame (ms) */
uint16_t duration;
/* Next frame */
struct anim_frame *next;
} anim_frame_t;
Le frame concerné est le rectangle (x,y,x+w,y+h) dans sheet, avec la durée duration, et on a le pointeur vers le frame suivant. Le "centre" est une donnée supplémentaire qu'on peut indiquer (via fxconv-metadata.txt) pour savoir, ici, où sont les pieds (pour dessiner le sprite au bon endroit).
C'est pas hyper dur à utiliser, l'affichage est même trivial :
{
if(!frame) return;
dsubimage(x - frame->cx, y - frame->cy, frame->sheet,
frame->x, frame->y, frame->w, frame->h, DIMAGE_NONE);
}
Et on peut suivre une animation juste en comptant combien de temps on a passé dedans :
{
/* Current frame */
anim_frame_t const *frame;
/* Time elapsed */
uint16_t elapsed;
} anim_state_t;
void anim_state_update(anim_state_t *state, fixed_t dt)
{
if(!state->frame) return;
state->elapsed += fround(dt * 1000);
if(state->elapsed < state->frame->duration) return;
/* Switch to next frame */
state->elapsed -= state->frame->duration;
state->frame = state->frame->next;
}
Mais c'est quand même pas une broutille, j'ai l'impression que dans l'ensemble ça reste spécifique au moteur utilisé. Je me dis que le plus simple c'est probablement si le code Python de fxconv fournissait la spritesheet compactée et l'équivalent de anim_frame_t mais en Python, et ensuite laisse l'utilisateur écrire son code de structure ? Comme ça c'est vraiment juste un outil Aseprite/Tiled et pas un bout de moteur.
-
Pour Tiled ça a l'air trivial de loin (juste une grille en CSV) mais dès qu'on veut faire les choses proprement, ie. définir un tileset avec quelles tiles ont des collisions, ça devient un peu difficile. C'est pour ça que j'imagine que ça vaudrait la peine d'avoir un code commun ? À voir, merci pour tes indications en tous cas.
Citer : Posté le 28/12/2021 10:48 | #
C'est très puissant le coup de l'animation, bien joué ! Après, ça restera forcément un peu spécifique… C'est plus ou moins toujours le même compromis entre un code qui fait beaucoup de chose mais qui est de ce fait moins souple, ou alors un code qui fait moins de chose, mais qui est très souple. De mon côté, je n'ai jamais réellement fait de sprites animés en C (même mes personnages ne bougeaient pas ou alors que pendant les déplacements et c'était un vieux trick pas propre )
Pour Tiled, c'est vrai que les collisions, j'y avais pas pensé… xD Donc oui c'est une bonne idée d'avoir un code commun je pense. Après je crois que Tituya a aussi géré les collisions avec fxconv pour Adoranda, mais il m'a confié que son code n'était pas des plus élégants (oui je balance, je suis comme ça, moi ). Dans mes codes où j'ai bidouillé des trucs avec fxconv et Tiled, je ne sais plus comment j'ai géré les collisions, ce qui est sûr c'est les collisions n'étaient pas indiqués sur le tileset.
Citer : Posté le 28/12/2021 10:58 | #
Salut, cool de demander du feedback !
Tu présentes ton convertisseur Aseprite comme plutôt niche à la lecture, faudrait que le format que t'utilises soit très simple et peu spécifique pour que je vois l'intérêt au dessus des strips. Edit : t'as répondu avec les détails depuis, ça a l'air super et général bien joué :o
Ah et tu as testé avec Libresprite ? Ce serait cool que l'option libre soit supportée
Les fonctionnalités avancées de Tiled sont ce qui le rendent intéressant pour moi. Si j'ai besoin d'une grille de nombres je continuerai d'utiliser mes propres outils. cute_tiled.h est la meilleure lib Tiled que j'ai utilisé ; si ton convertisseur s'approche, même de loin, de ct.h niveau fonctionnalités je vois définitivement l'intérêt
Le TSX j'en ai rien à faire perso mais si ça aide d'autres sure, why not?
Un truc auquel je pense maintenant, est-ce que tu penses pouvoir ajouter un champ optionnel aux images et potentiellement d'autres types qui contiennent le chemin relatif du fichier par rapport à la racine du projet ? Par exemple la valeur de bimg_player. serait (const char *)"res/player.png" si l'option fxconv est activée et (const char *)NULL otherwise. Ce serait vraiment très pratique
Merci pour ta considération !
Après j'aurai un autre truc à demander qui ne devrait pas coûter très cher, mais je te demanderai sur la shout si c'est possible avec fxconv ou si je devrais bricoler ça seul.
Citer : Posté le 28/12/2021 11:05 | #
Ah et tu as testé avec Libresprite ? Ce serait cool que l'option libre soit supportée
Sans avoir testé mais étant charger de garder le paquet AUR a jour, il n'y a rien qui empêche Libresprite d'exporter au format Aseprite (Il me semble que l'export par défaut est le même pour les deux)
Citer : Posté le 28/12/2021 19:14 | # | Fichier joint
Comme demandé par KikooDX, j'ai poussé sur le dépôt fxSDK des outils utiles pour collecter "toutes les images" d'un projet, ou "toutes les maps", ou autres questions du même type. C'est sur dev actuellement mais ça sera fusionné sous peu, je vais publier une nouvelle version de mes outils dans les prochains jours.
Je joins une démo de projet qui a déjà tout le code fonctionnel à titre d'exemple (à tester sur Graph 90+E).
Le but du jeu ici c'est de créer un tableau avec des pointeurs vers toutes les images du projet, plus un pointeur nul. Comme on va créer des données le plus naturel c'est de faire une conversion, donc je crée un fichier assets-cg/all-images.txt (vide) et je lui assigne dans fxconv-metadata.txt un type personnalisé. Je donne au passage le nom de la variable.
all-images.txt:
custom-type: all-images
name: all_images
Le type personnalisé, comme d'habitude est fourni par assets-cg/converters.py. Je saute la définition de la fonction convert() qui est toujours la même ; la partie intéressante c'est la fonction de conversion pour all-images.txt (la version dans l'archive est un peu commentée).
import pathlib
def convert_all_images(input, params):
o = fxconv.Structure()
for meta_file in pathlib.Path(input).parent.rglob("fxconv-metadata.txt"):
metadata = fxconv.Metadata(meta_file)
for file in [e for e in meta_file.parent.iterdir() if e.is_file()]:
params = metadata.rules_for(file)
if params is not None and params.get("type") == "bopti-image":
o += fxconv.ptr(params["name"])
o += fxconv.u32(0)
return o
Ce qu'on fait c'est qu'on cherche tous les fxconv-metadata.txt dans un sous-dossier de assets-cg (plus spécifiquement du dossier où all-images.txt se trouve, ce qui est pratique puisque ça permet de contrôler un peu finement ce qu'on collecte en déplaçant le fichier). On les charge individuellement avec l'objet Metadata() que je viens d'exposer dans l'API de fxconv, et ensuite on regarde tous les fichiers pour lesquels le paramètre "type" vaut "bopti-image". Dès qu'on en trouve on regarde sous quel nom ils sont convertis (le paramètre "name") et on ajoute à notre tableau un pointeur vers la variable concernée.
Dans main.c, on récupère ensuite le tableau et on en fait ce qu'on veut.
for(int i=0; all_images[i] != NULL; i++) {
/* ... */
}
Voilà voilà, comme vous pouvez le voir c'est pas dur (et ça montre la polyvalence de Python pour ce genre de tâches)
Citer : Posté le 28/12/2021 19:28 | #
C'est exactement ce que je voulais, merci Lephé !
Citer : Posté le 31/12/2021 10:56 | #
Nouvelle version : fxSDK 2.7.0
Release associée de gint : gint 2.7.0
Release associée de la fxlibc : fxlibc 1.3.0
Assez peu de changements ici, surtout des choses côté fxconv :
Citer : Posté le 05/01/2022 20:04 | #
Salut Léphé, j'ai une suggestion concernant le fxsdk, est-ce qu'il serait possible d'afficher la mémoire occupé par le programme à la fin de la compilation, comme lorsque l'on compile avec l'IDE Arduino.
- mémoire RAM prise par notre programme avec le pourcentage
- poids du g1a
A+
Citer : Posté le 05/01/2022 20:10 | #
Tu peux faire afficher la quantité de chaque région mémoire utilisée par le linker :
Pour le poids du g1a, tu peux le faire directement dans CMake. Ce n'est pas que je ne veuille pas l'ajouter au fxSDK mais quoi que je fasse ne vaudra jamais la liberté d'ajouter les commandes que tu veux.
Note que ça ajoute une commande après la compilation de ta cible, un mécanisme qui est déjà utilisé pour générer le g1a ; donc tu devrais mettre ça après generate_g1a().
COMMAND echo -n "Taille du G1A : "
COMMAND stat -c %s "${CMAKE_CURRENT_SOURCE_DIR}/myaddin.g1a")
Citer : Posté le 05/01/2022 20:23 | #
SUper, je pensais pas que ça pouvait être aussi simple
Par contre il me dit illegal option -c avec le stat
Citer : Posté le 05/01/2022 20:25 | #
Ah oui c'est un truc Linux qui marche pas sous Mac : https://stackoverflow.com/questions/10666570/binutils-stat-illegal-option-c#10666606
Y'a un million de commandes différentes pour afficher la taille d'un fichier, utilise celle qui passe (du/ls/stat)
Citer : Posté le 05/01/2022 20:26 | #
ok, merci
Citer : Posté le 29/01/2022 18:44 | #
Hey !
J'essaie d'utiliser mes animations aseprite sous Gint, comme ici.
Mais arrivé à la compilation, j'ai :
Voici une partie de mon CMakeLists.txt :
assets-cg/example.png
assets-cg/player_left.aseprite
assets-cg/player_right.aseprite
)
Et mon fxconv-metadata.txt :
type: bopti-image
name: img_example
player_left.aseprite:
custom-type: aseprite-anim
name_regex: player_left.aseprite anims_left
center: 8,19
next: Idle=Idle, Walking=Walking
profile: p8
player_right.aseprite:
custom-type: aseprite-anim
name_regex: player_right.aseprite anims_right
center: 8,19
next: Idle=Idle, Walking=Walking
profile: p8
Une idée ?
Citer : Posté le 29/01/2022 18:52 | #
Je crois que c’est pas builtin et que lephenixnoir a utilisé une lib externe
Citer : Posté le 29/01/2022 18:55 | #
Tu as bien fait ton convertisseur en python ?
https://gitea.planet-casio.com/oKLM/RogueLife/src/branch/master/assets-cg/converters.py
(Et de toute façon, vous pouvez pas dire le contraire)
MultipliCasio
RDM Calculs
Back Mirror
A Switch To The Top C