libg1m - une interface mieux pensée que son format
Posté le 01/11/2016 10:05
Le saviez-vous ? L'ensemble des formats de fichiers dont vous avez l'habitude (g1m, g1e, g1a, g3a, ...) sont en réalité des déclinaisons d'un seul même format ? Ce format, comme d'habitude, n'a pas vraiment de nom public, donc je l'ai nommé par le nom de l'une de ses déclinaisons les plus complexes, le G1M.
Ça fait un petit moment que je souhaite faire une lib qui soit capable de lire (d'analyser) et d'écrire dans toutes ces déclinaisons (ou au moins les plus communes), avec une interface assez facile d'accès (parce que le faire directement, c'est quand même bien casse-gueule). Eh bien ça y est, je me suis lancé dessus depuis quelques temps. Pour l'instant, je ne m'occupe que de la partie lecture pour avoir une idée globale de toutes les déclinaisons du format, pour savoir ensuite comment je stockerai ça pour le renvoyer à l'utilisateur.
Les sources sont d'ores et déjà disponibles sur ma forge personnelle.
Pour le moment, je ne me concentre que sur la capacité d'analyse de la lib, puis je me concentrerai sur le fait de lire pour renvoyer à l'utilisateur. Ne comptez pas sur une capacité d'écriture avant un moment.
Les formats actuellement "gérés" (ou en cours de décortiquage) sont :
-
G1A,
G3A : add-ins pour les calculatrices monochromes et Classpads (/Prizm) ;
-
G[1-3][MR] : sauvegardes de la MCS (mémoire principale) ;
-
G[1-3]E : e-activities (documents) ;
-
G3P : pictures pour les Prizm ;
-
C2P : pictures pour les Classpads ;
-
G1S : archive ;
-
G1L,
G3L : fichiers de locale.
-
G1N : fichiers de
function keys. (merci Simon Lothar <3)
Il me reste encore pas mal de subtilités à comprendre/tester, comme pas mal de types de strips pour les e-activities (calculs, UI.main, ...) ou les BCD. Aussi, en plus de ces formats-là, d'autres formats sont sur ma TODO list (voir plus bas).
Pour les sauvegardes de la mémoire principale, les éléments suivants sont gérés :
-
Programmes
-
Spreadsheets
-
Captures
-
Pictures
-
Listes
-
Matrices
Mon test kit actuel avec les fichiers, sources et scripts de test
ICI (et les
anciens au cas où)
Ce projet possède un sous-projet : la référence FONTCHARACTER,
n'hésitez pas à aller voir si vous voulez découvrir l'encodage qu'utilisent les calculatrices CASIO.
Citer : Posté le 01/12/2016 17:18 | #
Donc pire que ce que je pensais.
Et en fait, j'ai juste récupéré les G1S de ce programme-là (et des C2P random trouvés sur TI-Planet). (je vois pas trop en quoi la formulation est étrange)
Mon blog ⋅ Mes autres projets
Citer : Posté le 01/12/2016 17:44 | #
Bah, le "j'ai pu dégoter" alors qu'on en a tous au moins trois sur notre ordinateur, parfois 10
Citer : Posté le 12/12/2016 16:20 | #
Quelques petites nouvelles du coup :
- concernant les fichiers de type MCS (G*M, G*R), il y a encore pas mal de sous-fichiers dont le format est inconnu, je ne sais lire que les plus classiques (donc pas encore une save complète, par exemple) ;
- les fichiers de langue (G1L, G3L) sont a priori totalement managés, et les G1N ne devraient pas tarder, merci à Simon Lothar pour ça ! ;
- faut toujours que je corrige la lecture des fichiers G3P, et les fichiers C2P ne sont pas gérés (ah, la zlib et l'obfuscation made-in-Casio <3) ;
- à l'aide de quelques scripts Python exploitant la référence FONTCHARACTER, je suis capable de lire, en unicode, le contenu de fichiers de langue (cf. fichiers de test) ;
- il faut toujours que je corrige la lecture des add-ins (oui, je sais, le format le plus simple, mais justement, c'est pas celui sur lequel je me concentre).
N'hésitez pas à jeter un œil sur les sources si vous êtes curieux
Mon blog ⋅ Mes autres projets
Citer : Posté le 12/12/2016 16:32 | #
Super !
Hésite pas à me dire si tu implémentes l'écriture des g1a, ça fera un composant de moins pour le fxSDK
Citer : Posté le 17/12/2016 02:20 | #
Bon, j'ai changé la façon dont je gère la MCS, et ça marche beaucoup mieux que l'ancienne (c'est sans doute beaucoup plus proche de la manière dont CASIO a géré son format... ça a réglé quelques absurdités). Maintenant, même si je gère les grands classiques parmi les fichiers MCS, il reste une myriade de types de fichiers totalement inconnus (et ayant peu d'intérêt, mais je veux faire quelque chose de complet). Du coup, je pourrais proposer un concours de reverse engineering, à des fins utiles puisque le format déduit pourrait se retrouver dans la lib et ainsi, pourrait être accessible à tous. Qu'en pensez-vous ?
(le principal souci étant que c'est un concours plus technique que les CPC requiérant des add-ins. Je pourrais toujours commencer le portage de cette lib pour d'autres plateformes comme celle de Microchiotte à l'occasion de la préparation de ce concours)
Mon blog ⋅ Mes autres projets
Citer : Posté le 17/12/2016 13:59 | #
Ça va être assez technique. Déjà il faudrait disposer d'échantillons des types inconnus, savoir à quoi ils servent (globalement, connaître le nom du fichier, tel que vu par la MCS) et dans l'idéal pouvoir les ouvrir (genre de la même manière que tu peux ouvrir un S-SHEET dans l'application associée). Dans tous les cas, pas sûr qu'on arrive à grand-chose
Citer : Posté le 17/12/2016 15:57 | #
Pour les échantillons, c'est pas un problème, la libg1m est quasi-prête à extraire n'importe quel échantillon inconnu, il suffit d'adapter un tout petit peu (ce que je vais de toute façon faire pour que la lib soit commode pour ça, concours ou non). Après, pour trouver leur rôle, leur contenu et surtout comment il est organisé, ça ne sera effectivement pas facile, mais ça reste pas mal de le faire un jour. Et puis, un concours, ça peut animer un peu (même si c'est du reverse engineering pas forcément accessible aux débutants, et qu'aucun lot ne sera à pourvoir, sans doute)
Mon blog ⋅ Mes autres projets
Citer : Posté le 19/12/2016 04:01 | # | Fichier joint
Les g1k n'ont absolument rien à voir avec les autres fichiers g1m (ils commencent même pas par le header normal) et ne sont pas destinés à être transférés sur la calto, mais comme j'en ai sous la main les v'la en pièce jointe si tu veux (mais je doute que ça te servira). Il y en a 2 dans chaque dossier.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 19/12/2016 12:33 | #
Hm, ce header me dit quelque chose (j'ai dû voir ça sur d'autres fichiers), je garde ça en attendant de retrouver. Merci zz <3
Mon blog ⋅ Mes autres projets
Citer : Posté le 20/12/2016 23:29 | # | Fichier joint
Bon, du coup, j'ai ajouté tout ce qu'il fallait pour de la cross-compilation vers Microsoft Windows (mais a priori, pas de compilation sur MS-Windows directement). Comme preuve de ça, voici la version MS-Windows de mcsfile, un petit utilitaire file-like qui se manipule par lignes de commandes (en gros, faut utiliser cmd pour s'en servir), qui m'a pris à peine une demi-heure à faire.
En faisant un autre utilitaire, je pourrais lancer un concours (ou tout simplement, un appel, mais c'est moins convivial) pour se lancer dans le reverse engineering des fichiers inconnus de la MCS. Les codes sources sont toujours disponibles (sous GPLv2), par ici :
https://forge.touhey.fr/lib/libg1m
https://forge.touhey.fr/casio/software/mcsfile <lien mort, voir ci-après pourquoi>
Ajouté le 22/12/2016 à 01:29 :
De la même façon que j'ai fait pour les utilitaires P7, j'ai créé les g1mutils, où il n'y a que mcsfile pour le moment (d'autres viendront certainement), histoire de garder ça organisé.
Ajouté le 28/01/2017 à 01:23 :
Les g1mutils (donc mcsfile seul) ont fusionné avec les p7utils (que je ne pense pas renommer pour autant). La libp7 et la libg1m sont deux poids lourds, et même s'ils ont la même structure de projet, je ne pense pas les fusionner ; la structure des trois projets principaux restera donc telle quelle, la libp7, la libg1m et les p7utils (et les projets gravitant autour d'eux/les ayant en dépendance).
Ah, et pour ceux qui en doutaient, non, la libg1m ne sera pas portée pour calculatrice : en effet, pour pas mal de fichiers, tels que les fichiers G1S, elle requiert bien plus que 512 Ko de RAM.
Ajouté le 06/03/2017 à 15:19 :
J'avance, et pour le montrer, voici un exemple de ce à quoi un usage peut ressembler (lister les programmes et leur mot de passe). A noter que je compte encore simplifier l'interface par rapport à ce qu'il y a là. (une version en couleur est disponible ici)
#include <string.h>
#include <errno.h>
#include <libg1m.h>
#define DIM (FC_MAX_UNI * 8 + 1)
int main(int ac, char **av)
{
if (ac != 2 || !strcmp(av[1], "-h") || !strcmp(av[1], "--help")) {
fprintf(stderr, "Usage: %s <path/to/file>\n", av[0]);
return (1);
}
g1m_t *handle = NULL;
int err = g1m_open(&handle, argv[1], g1m_type_mcs);
if (err) {
fprintf(stderr, "An error occured: %s\n", err == g1m_error_nostream
? strerror(errno) : g1m_strerror(err));
return (1);
}
for (int i = 0; i < handle->count; i++) {
g1m_mcsfile_t *f = handle->files[i];
if (!f || f->head.type != g1m_mcstype_program)
continue;
/* on suppose que les multi-caractères d'une longueur supérieure à 1
* caractère ne sont pas autorisés dans les noms de fichiers et
* mots de passe. */
wchar_t name[DIM], pass[DIM];
fc_mbstous(name, f->head.name, DIM);
fc_mbstous(pass, f->head.password, DIM);
printf("* %ls (", name);
if (pass[0]) printf("mot de passe: %ls)\n", pass);
else printf("pas de mot de passe)\n");
}
g1m_free(handle);
return (0);
}
Mon blog ⋅ Mes autres projets
Citer : Posté le 06/03/2017 18:24 | #
Selon moi il faudrait aussi (outre le code en C) faire une documentation g1m, pour que ton travail serve aussi à ceux qui ne codent pas en C (je pense à mes projets en java, mais aussi aux utilitaires du site en php, en python...)
Donc documenter le format général d'un g1m, ses sous-parties, et les autres formats si besoin.
Je pense qu'un schéma sera mieux que du texte, donc ça ressemblerait à ça :
Bien entendu le schéma serait de meilleure qualité mais ce n'est qu'un exemple.
On mettrait aussi la taille des différents morceaux, une liste des types, etc.
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 06/03/2017 18:27 | #
Concernant la documentation, comme il me semblait te l'avoir expliqué (mais pas publiquement), je documente les structures utilisées dans les headers au fur et à mesure que je découvre leurs secrets via les documentations et codes sources que je grapille çà et là :
https://github.com/cakeisalie5/libg1m/blob/master/include/libg1m/format.h
https://github.com/cakeisalie5/libg1m/tree/master/include/libg1m/format
Et je n'écris pas encore de documentation à côté, puisque je ne sais pas encore tout des formats et qu'il reste encore possiblement quelques points d'ombre ou incorrects.
Mais je trouve honnêtement plus propre de faire un portage Java, comme je compte en faire un pour Python. Et encore, pour ça, il vaut mieux attendre la release, parce qu'actuellement, l'API change beaucoup pour s'adapter au maximum de situations.
Mon blog ⋅ Mes autres projets
Citer : Posté le 06/03/2017 20:03 | # | Fichier joint
Voilà en pièce jointe un g1m contenant tous les opcodes/caractères
Ecrivez vos programmes basic sur PC avec BIDE
Citer : Posté le 16/03/2017 14:34 | #
Moi ça va, et vous ?
$GLOBAL/ALPHAMEM: alpha memory
$GLOBAL/SETUP: setup
@CONICS/conicmem: unknown content (4 octets)
@DYNA/COND: unknown content (44 octets)
@E-CON2/Econ3Now: unknown content (300 octets)
@FINANCE/fina_mem: unknown content (252 octets)
@RECUR/RECRG: unknown content (168 octets)
@REV2/CLIP: unknown content (8 octets)
@REV2/NAT_CLIP: unknown content (8 octets)
@RUNMAT/REPLAY: unknown content (16 octets)
@RUNMAT/RUN2D1: unknown content (772 octets)
@SSHEET/SHEET: spreadsheet (0 columns, 0 rows)
@SSHEET/SS: spreadsheet (4 columns, 2 rows)
@STAT/C_CND: unknown content (12 octets)
@STAT/G_CND: unknown content (96 octets)
@STAT/G_CNDEX: unknown content (448 octets)
@STAT/STATap: unknown content (312 octets)
@STAT/STATapX: unknown content (196 octets)
@TABLE/RANGE: unknown content (36 octets)
main/1: unknown content (16 octets)
main/1LIST1: list 1 (1 columns)
main/1LIST1: list 1 (from listfile 1, 1 columns)
main/1LIST2: list 2 (1 columns)
main/1LIST2: list 2 (from listfile 1, 1 columns)
main/FACTOR: unknown content (24 octets)
main/MAT_A: matrix A (13 columns, 7 rows)
main/MAT_B: matrix B (4 columns, 4 rows)
main/PICT1: picture 1 (double 128x64 image)
main/STATV0: unknown content (160 octets)
main/STATV1: unknown content (28 octets)
main/STR1: string 1
main/STR2: string 2
main/VWIN: unknown content (132 octets)
system/DESSIN: program (no password)
system/G'BLCKJK: program (no password)
system/G'DEMIN: program (no password)
system/G'OHNO: program (no password)
system/G'POM: program (no password)
system/G'SNAKE: program (no password)
system/G'SQUEST: program (no password)
system/H'BITDEV: program (no password)
system/H'TETDEV: program (no password)
system/M'CBEZ: program (no password)
system/M'PGCD: program (no password)
system/M'PREM: program (no password)
system/MINI: program (no password)
system/T'BITE: program (no password)
system/T'KEY: program (no password)
system/T'STR: program (no password)
system/Z'BALL: program (no password)
system/Z'BAZ: program (no password)
system/Z'BAZR: program (no password)
system/Z'DD: program (no password)
system/Z'DEPRIM: program (no password)
system/Z'DOG: program (no password)
system/Z'DVTEST: program (no password)
system/Z'EXE: program (no password)
system/Z'FLECHE: program (no password)
system/Z'HACKR: program (no password)
system/Z'IE: program (no password)
system/Z'IENU: program (no password)
system/Z'NON: program (no password)
system/Z'OUI: program (no password)
system/Z'PELLE: program (no password)
system/Z'REACT: program (no password)
system/Z'SELEC: program (no password)
system/Z'SH: program (no password)
system/Z'SHTDWN: program (no password)
system/Z'UTILE: program (no password)
system/Z'YOLO: program (no password)
cake@66 :: lib/libg1m » mcsfile tests/cas/EULER.CAS
EULER: program (no password)
cake@66 :: lib/libg1m » mcsfile tests/casemul/test.cas
List 1: list 1 (1 columns)
Mat C: matrix C (1 columns, 1 rows)
Picture1: capture 1 (128x64)
Mon blog ⋅ Mes autres projets
Citer : Posté le 16/03/2017 16:38 | #
Oh ho, voilà qui est prometteur Il affiche aussi la listes des fonctions et sections des add-ins ?
Il me faut cet utilitaire. Quand est-ce que tu réhabilites ou changes le lien qui est en haut de la page ? Je n'ai rien trouvé sur la forge de PC, donc rien à pull pour tester.
Citer : Posté le 16/03/2017 16:45 | #
L'utilitaire est dans les p7utils : https://github.com/cakeisalie5/p7utils/tree/master/src/mcsfile
Il n'est pas construit par défaut, il faut utiliser les targets all-mcsfile et install-mcsfile.
Q: Que fout l'utilitaire dans les p7utils alors qu'il a rien à voir avec le protocole 7 ?
A: Parce que le projet P7 est devenu plus large que le simple protocole de communication, c'est devenu un projet de libération du logiciel plus large du monde CASIO. La libg1m y sera intégrée lorsqu'elle sera prête.
Bien entendu, je ne conseille pas l'usage de la libg1m et de mcsfile pour le moment, c'est du en cours de développement.
Ajouté le 20/03/2017 à 02:32 :
Du coup, j'ai commencé à gérer l'encodage (la création) de fichiers à l'aide de la libg1m, et il gère déjà un type : les add-ins pour calculatrices fx (monochromes) !
https://github.com/cakeisalie5/libg1m/blob/master/src/encode/main.c
https://github.com/cakeisalie5/libg1m/blob/master/src/encode/addin.c
Cela dit, je n'ai fait que ré-encoder des fichiers existants (g1m_open pour obtenir un handle à partir d'un fichier que la lib va ouvrir et lire, et g1m_write pour encoder le contenu du handle dans un fichier qu'elle va elle-même ouvrir). Histoire que vous ayiez une idée de comment utiliser tout ça, voici le test que j'ai utilisé :
#include <string.h>
#include <errno.h>
int main(int ac, char **av)
{
if (ac != 3) return (0);
/* get file */
g1m_t *handle; int err;
if ((err = g1m_open(&handle, av[1], 0))) {
printf("Could not open file: %s\n", g1m_strerror(err));
if (err == g1m_error_nostream)
printf("Errno was %d: %s\n", errno, strerror(errno));
}
/* write file */
if ((err = g1m_write(handle, av[2])))
printf("Encountered an error while writing: %s\n", g1m_strerror(err));
/* free the handle */
g1m_free(handle);
return (0);
}
De plus, je suis encore loin d'une quelconque release : il reste encore beaucoup de types que je ne gère pas (me dit mon sherpa) en décodage, donc j'ignore quand j'ajouterai l'encodage de formats plus complexes tels que les archives MCS (g1m/g2m/g1r/g2r).
Aussi, je ne conseille pas l'usage grand public de la lib pour le moment (s'il n'y a pas de release, c'est pour une raison), mais les curieux peuvent tout de même y jeter un oeil
Mon blog ⋅ Mes autres projets