Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » [SDK] MonochromeLib - une lib graphique monochrome
PierrotllHors ligneAncien administrateurPoints: 5488 Défis: 41 Message

[SDK] MonochromeLib - une lib graphique monochrome

Posté le 09/06/2010 02:22

MonochromeLib, qu'est ce que c'est ?
MonochromeLib est une bibliothèque de dessin pour le SDK Casio Graph 85.
Elle fournit aux développeurs des fonctions optimisées pour tracer toute sorte de choses à l'écran.
Chaque fonction de MonochromeLib est bien plus rapide que son équivalent dans fxlib.h, et elle fournit de nombreuses fonctionnalités supplémentaires.

Comment l'utiliser
Pour utiliser la bibliothèque, copiez les 2 fichiers dans le dossier de votre projet, ajoutez MonochromeLib.c à votre projet (dans la fenêtre "Files in project" dans le SDK), ajoutez #include "MonochromeLib.h" au début de votre code.
Pour n'ajouter à votre projet que les fonctions dont vous avez besoin, chaque fonction est protégée par un #ifdef, et les #define de chaque fonction sont commentés par défaut.
Pour pouvoir utiliser une fonction, il suffit d'éditer MonochromeLib.h et de décommenter les #define des fonctions que vous voulez utiliser.
/!\ Important
Si vous rencontrez une erreur de compilation de ce type :
** L2310 (E) Undefined external symbol "_ML_pixel" referenced in "C:\...\CASIO\fx-9860G SDK\Projet\Debug\MonochromeLib.obj"
et que le #define de la fonction en question est bien actif dans MonochromeLib.h, alors il faut juste recompiler MonochromeLib.c
Pour cela, Utilisez la fonction Project > Rebuilt all dans le SDK. Si cela ne résoud pas le problème, supprimez le dossier Debug de votre projet, et recompilez normalement.

N'attendez plus !
Une documentation complète est maintenant fournie dans l'archive zip, en anglais et en français.


Questions récurrentes :

Problème : voici mon code, le compilateur ne veux pas le compiler :
unsigned char image[] = { ... };

ML_clear_vram();
ML_BMP_OR(image, 21, 42, 34, 34);
ML_clear_vram();

Solution : toutes les fonctions de MonochromeLib s'appellent en minuscule : les seules majuscules sont celles du "ML". Relisez la doc ou le wiki, et regardez l'orthographe exacte de la fonction.


Version actuelle : 22 novembre 2011
Télécharger MonochromeLib


Pages : Précédente1, 2, 3, 4
KirafiHors ligneMembrePoints: 2014 Défis: 10 Message

Citer : Posté le 19/01/2016 19:22 | # | Fichier joint


Hum... remplace ton fichier Monochrome.lib par celui que j'utilise (en PJ).
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
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)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (é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)
KirafiHors ligneMembrePoints: 2014 Défis: 10 Message

Citer : Posté le 19/01/2016 19:23 | # | Fichier joint


Et le Header
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
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)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (é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)
Matt36230Hors ligneMembrePoints: 1868 Défis: 0 Message

Citer : Posté le 19/01/2016 19:23 | #


le .c ?
Le header quelle est cette bête ?

Ajouté le 19/01/2016 à 19:25 :
Ca ne change rien
KirafiHors ligneMembrePoints: 2014 Défis: 10 Message

Citer : Posté le 19/01/2016 19:25 | #


Ben c'est les .c et .h de Monochrome.lib , à inclure dans le projet (tu sais la petite fenêtre en long à gauche ).
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
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)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (é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)
Matt36230Hors ligneMembrePoints: 1868 Défis: 0 Message

Citer : Posté le 19/01/2016 19:27 | #


C'est bon je venais de comprendre

Cela ne fonctionne toujours pas

Voici ce que me dit le sdk quand je build
Cliquer pour enrouler
Executing Hitachi SH C/C++ Compiler/Assembler phase

set SHC_INC=C:\Users\jdc\Desktop\Calculatrice\SDK\OS\SH\include
set PATH=C:\Users\jdc\Desktop\Calculatrice\SDK\OS\SH\bin
set SHC_LIB=C:\Users\jdc\Desktop\Calculatrice\SDK\OS\SH\bin
set SHC_TMP=C:\Users\jdc\Documents\CASIO\fx-9860G SDK\Mes projets\Test lib\Debug

Executing Hitachi OptLinker04 phase

"C:\Users\jdc\Desktop\Calculatrice\SDK\OS\SH\bin\Optlnk.exe" -subcommand=C:\Users\jdc\AppData\Local\Temp\hmk26A5.tmp

** L2310 (E) Undefined external symbol "_ML_line" referenced in "C:\Users\jdc\Documents\CASIO\fx-9860G SDK\Mes projets\Test lib\Debug\TestLib.obj"

Optimizing Linkage Editor Abort

HMAKE MAKE UTILITY Ver. 1.1
Copyright (C) Hitachi Micro Systems Europe Ltd. 1998
Copyright (C) Hitachi Ltd. 1998


ERROR: Process failed with return code: 1
Build was not successful.

KirafiHors ligneMembrePoints: 2014 Défis: 10 Message

Citer : Posté le 19/01/2016 19:34 | #


Tu dois avoir 2 fois le même nom de fonction ML_Line() dans tout ton code, cherche dans tout tes .c le doublon et supprime celui qui ne se trouve pas dans Monochrome.lib .
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
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)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (é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)
Matt36230Hors ligneMembrePoints: 1868 Défis: 0 Message

Citer : Posté le 19/01/2016 19:37 | # | Fichier joint


Ba il est dans testlib.c mais je suppose que c'est normal puisque c'est mon programme

Sinon je n'ai que usefull.c en autre .c. Et il n'est pas dedans

(j'ai mis les sources en fichier joint si vous voulez tester de build)
KirafiHors ligneMembrePoints: 2014 Défis: 10 Message

Citer : Posté le 19/01/2016 19:52 | #


Nan Mais ... Déjà t'as pas Ajouté les MonochromeLib.c et usefull.c au projet, je parle pas des includes , Genre dans la fenêtre à gauche du SDK, il y a "Sources Files", tu fais clic droit -> Add et tu sélectionnes tes fichiers .c

Ajouté le 19/01/2016 à 19:53 :
Et ensuite, tu as viré des trucs auquel fallait pas touché :boulet3: (c'est pas comme si c'était marqué en commentaire quoi...)
#pragma section _BR_Size
unsigned long BR_Size;
#pragma section


#pragma section _TOP

int InitializeSystem(int isAppli, unsigned short OptionNum)
{
    return INIT_ADDIN_APPLICATION(isAppli, OptionNum);
}

#pragma section

Rajoutes ça à la fin du programme de TestLib.c .
iPod
Pour des parties rapides
Jusqu'où pourras-tu aller dans ce jeu "partie rapide" qu'est Dextris (élu Jeu Du Mois)
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)
Autres
Franchement ils valent le coups
Deviens l'amiral de la marine dans SeaRush (jeu concours) (é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)
Matt36230Hors ligneMembrePoints: 1868 Défis: 0 Message

Citer : Posté le 19/01/2016 19:57 | #


AAAAAAAAAAAHHHHHHHHH !!!
Bah ça fonctionne mieux

Merci merci merci mille fois kirafi et Fife et désolé de vous avoir embêté pour un truc aussi idiot au final


EltoredoHors ligneModérateurPoints: 4291 Défis: 35 Message

Citer : Posté le 19/01/2016 19:57 | #


Vous réglez un petit problème en messages qui se serait réglé en 2 minutes sur TS / Teamviewer / Skype, j'ai déjà eu à faire avec ce genre de soucis et c'est bien chiant d'en trouver la source x)
La procrastination est une vertu. (voir ma description pour comprendre mon raisonnement)
ZezombyeEn ligneRédacteurPoints: 1595 Défis: 12 Message

Citer : Posté le 07/08/2016 23:42 | #


Comment implémenter une fonction qui ne clear la vram que dans un rectangle ? (similaire à BDisp_AreaClearDDVRAM())

void ML_clear_vram() {
    int i, end, *pointer_long, vram;
    char *pointer_byte;
    vram = (int)ML_vram_adress();
    end = 4-vram&3;
    pointer_byte = (char*)vram;
    for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
    pointer_long = (int*) (vram+end);
    for(i=0 ; i<255 ; i++) pointer_long[i] = 0;
    pointer_byte += 1020+end;
    end = vram&3;
    for(i=0 ; i<end ; i++) pointer_byte[i] = 0;
}
void ML_clear_area_vram(int x1, int y1, int x2, int y2) {
//?
}


Je vois pas du tout comment faire parce que je comprends rien à ce qui se passe (quelle signification a la valeur de end, pourquoi il fait 3 boucles for au lieu d'une ?)
Divers jeux : Puissance 4 - Chariot Wars - Sokoban
Ecrivez vos programmes basic sur PC avec BIDE
Cakeisalie5Hors ligneMembre de CreativeCalcPoints: 1730 Défis: 10 Message

Citer : Posté le 07/08/2016 23:53 | #


En fait, faut voir ML_clear_vram comme un memset(<vram>, 0, 1024);.

La VRAM, c'est facile à manipuler, puisque ce sont des octets pleinement utilisés, y a pas de questions de fill bits, pas de coordonnées de l'utilisateur à prendre en compte, etc.

Un rectangle, c'est déjà moins évident, à cause du point central : est-ce que la coordonnée horizontale tombe en plein milieu d'un octet ? Est-ce que cette coordonnée plus la longueur du rectangle tombe également en plein milieu ?

Un exemple d'implémentation (pas testé, sans aucun doute optimisable), où tout est supposé valide :

static void clear_rectangle_line(unsigned char *vram, int w, int offset)
{
    // premiers bytes en travers
    while (w >= 8 ) {
        *vram &= ~(255 >> offset);
        *++vram &= ~(255 << (8 - offset));
        w -= 8;
    }
    // dernier byte non entier (voire nul)
    int byte = ~(255 << w); // le tout bitwise and 255 (mais normalement y a pas besoin)
    *vram &= ~(byte >> offset);
    *++vram &= ~(byte << (8 - offset));
}

void clear_rectangle(int x, int y, int w, int h)
{
    unsigned char *vram = ML_vram_address();
    // on avance au premier octet qui nous intéresse
    vram += y * 16 + x / 8;
    // pour chaque ligne
    while (h--) {
        clear_rectangle_line(vram, w, x % 8 );
        vram += 16; // ligne suivante
    }
}


Promotion ordinaire sur les inscriptions sur Planète Casio : en ce moment, c'est gratuit !
Besoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
LephenixnoirEn ligneAdministrateurPoints: 14138 Défis: 136 Message

Citer : Posté le 08/08/2016 08:02 | #


Pour répondre à la question de Zezombye (ce que Cake n'a pas fait x)), il y en fait un os dans la technique de manipulation de la VRAM. Le principe est pourtant simple : plus on écrit de bits à la fois et plus ça va vite. On veut donc utiliser des int, comme la boucle du milieu : ça fait 32 pixels écrits par opération

Seulement voilà, pour écrire 4 octets il faut une adresse multiple de 4 (principe inhérent à de très nombreux processeurs aujourd'hui). Et la VRAM du système n'est pas alignée sur une adresse multiple de 4. Elle se termine par 0xd de mémoire. Du coup elle n'est pas non plus alignée sur une adresse multiple de 2 octets.

Qu'à cela ne tienne : on voit bien que si on écrit les premiers octets on va rapidement atteindre une adresse multiple de 4. C'est ce qu'il fait : la première boucle traite au plus trois octets et les écrit un par un. Ensuite on atteint une adresse multiple de 4, donc il utilise un pointeur en int * et il écrit les octets 4 par 4 (dans le même temps processeur !). Là c'est la partie où la vitesse est élevée ! Enfin, il y a quelques octets à la fin qui restent, donc il les écrit à la main, un par un, dans la dernière boucle.

Note au passage que privilégier les opérations sur 32 bits est la première optimisation à surveiller quand on manipule le dessin : c'est celle qui se montre généralement la plus efficace.

Pour le coup du rectangle, j'ai trouvé une méthode simple pour gérer ça dans gint. Le principe est de dire qu'un rectangle, c'est un certain nombre de fois la même ligne. Du coup si on arrive à décrire correctement une ligne, on est bons. Il y a 16 octets de VRAM par ligne, on peut donc écrire une fonction qui prend deux paramètres (x1, x2) et qui nous renvoie 16 char dans lequel le rectangle est représenté par des bits à 1.

Par exemple (ici avec 2 char, pour faire court. J'ai inclus les deux points) :
getMasks(5, 13);
>> [ 0000 0111,  1111 1100 ]

Le code est le suivant (adapté depuis celui de gint où on utilisait 4 int, il peut rester des erreurs) :
void getMasks(int x1, int x2, uint8_t *masks)
{
    int l1 = x1 >> 3;
    int l2 = x2 >> 3;
    int i = 0;

    while(i < l1)  masks[i++] = 0x00;
    while(i <= l2) masks[i++] = 0xff;
    while(i < 16)  masks[i++] = 0x00;

    x1 &= 7;
    x2 = ~x2 & 7;
    masks[l1] &= (0xff >> x1);
    masks[l2] &= (0xff << x2);
}


Le reste est assez trivial, il suffit d'itérer sur la mémoire et d'appliquer un ET logique entre chaque ligne de VRAM et notre ligne de masques :
void clearArea(int x1, int y1, int x2, int y2)
{
    uint8_t masks[16];
    getMasks(x1, x2, masks);

    int begin = y1 << 4;        // Offset of line 'y1'
    int end = (y2 + 1) << 4;    // Offset of line 'y2' + 1

    for(int i = begin; i < end; i++) vram[i] &= ~masks[i & 15];
}

Je crois que j'ai tout dit. Gint le fait sur des int donc typiquement ce serait 4 fois plus rapide.
Pages : Précédente1, 2, 3, 4

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2019 | Il y a 61 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd