Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » [SDK] MonochromeLib - une lib graphique monochrome
Pierrotll Hors ligne Ancien administrateur Points: 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


Kirafi Hors ligne Membre Points: 2180 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)
Kirafi Hors ligne Membre Points: 2180 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)
Matt36230 Hors ligne Membre Points: 1888 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
Kirafi Hors ligne Membre Points: 2180 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)
Matt36230 Hors ligne Membre Points: 1888 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.

Kirafi Hors ligne Membre Points: 2180 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)
Matt36230 Hors ligne Membre Points: 1888 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)
Kirafi Hors ligne Membre Points: 2180 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)
Matt36230 Hors ligne Membre Points: 1888 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


Eltoredo Hors ligne Modérateur Points: 4301 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)
Zezombye Hors ligne Rédacteur Points: 1756 Défis: 13 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
Cakeisalie5 En ligne Ancien administrateur Points: 1910 Défis: 11 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 !

Mon blogBesoin d'utilitaires de transfert vers et depuis la calculatrice sous GNU/Linux ?
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 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.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 25/12/2019 02:29 | #


Bonsoir, comme j'ai fait une installation toute fraîche pour prog sur Linux j'ai essayé de refaire marcher MonochromeLib avec fxlib. Par défaut le code compile (si on remplace #include <stdlib.h> par #include <fxlib.h>) mais ne s'exécute pas correctement sur la calculette. J'avais déjà rencontré le problème mais grâce à ElDarkPhoenix on a corrigé le problème. Comme je me suis repenché sur le problème en cette soirée j'en ai profité pour faire un relooking au code qui gère les syscalls... de plus ça permet aux optimisations de gcc de fonctionner.

Je passe de ça :
static int SysCallCode[] = {0xD201422B,0x60F20000,0x80010070};
static int (*SysCall)( int R4, int R5, int R6, int R7, int FNo ) = (void*)&SysCallCode;
char* ML_vram_adress()
{
    return (char*)((*SysCall)(0, 0, 0, 0, 309));
}


à ça :
const int SysCallCode[] = {0xD201422B, 0x60F20000, 0x80010070};
char *(*SysCall)(int, int, int, int, int) = (volatile void *)&SysCallCode;
char *ML_vram_adress() { return SysCall(0, 0, 0, 0, 309); }


J'ai enlevé les static car j'ai l'impression que ça sert à rien dans ce cas et j'ai changé les types de retour pour éviter les cast non obligatoires... Le mot-clé volatile je l'ai posé un peu au pif mais sans lui les optimisations de gcc passent pas

J'utilise toujours fxlib car sa fonction de rafraîchissement d'écran est compatible avec le mode projecteur de la casio (p7screen) J'ai pas vu de fonction qui peut faire ça avec gint.
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 25/12/2019 08:32 | #


Merci pour l'info ! Le changement que tu as fait ressemble pas mal à la façon d'appeler les syscalls sur SH4. L'ancienne méthode d'appels de syscalls en C ne marchait pas sur SH4 pour je ne sais quelle raison (et le fait que le compilo soit là, bon...).

Tu as certainement aussi mis du volatile dans ML_display_vram() sur les registres de l'écran, c'était nécessaire la dernière fois que j'ai compilé ML avec GCC avec optis.

En effet, gint ne supporte pas le projecteur, et je doute qu'il le fasse dans le futur.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 25/12/2019 11:44 | #


Bon ça me rassure que tu valides mon bout de code... Je n'ai pas touché à ML_display_vram() car je ne l'utilise pas... D'après mes souvenirs elle ne supporte pas non plus le mode projecteur.
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 25/12/2019 11:46 | #


Yup c'est le cas, le protocole du projecteur intervient dans une sous-fonctions appelée à la fin de Bdisp_PutDisp_DD(), j'ai désassemblé dans ce coin-là une fois.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Ziqumu Hors ligne Membre d'honneur Points: 3055 Défis: 9 Message

Citer : Posté le 27/12/2019 04:37 | #


Juste pour info, l'ancienne façon d'appeler du code ne marche plus parce qu'il vient copier SysCallCode dans une zone non executable de la mémoire et ça plante quand on jump dessus (et cette zone était executable en SH3). Alors que si tu mets en const, il va jumper directement dans la mémoire où le programme est stocké puisque c'est une constante, pas besoin de copier le tableau.

C'était un des fix de SH4CompatibilityTool : https://gitea.planet-casio.com/Ziqumu/SH4compatibilityTool/src/branch/master/DOCUMENTATION.md#monochromelib-and-syscall-call-method
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 27/12/2019 08:21 | #


Ah right, le coup de la RAM virtualisée non exécutable. C'est ce qu'on gagne à vouloir coder ça en C... x)
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Parit3y Hors ligne Membre Points: 51 Défis: 0 Message

Citer : Posté le 16/08/2020 20:49 | #


aucune des solutions ne marche dans mon cas
Lephenixnoir Hors ligne Administrateur Points: 24232 Défis: 170 Message

Citer : Posté le 16/08/2020 20:53 | #


Pour appeler des syscalls ? Il y a probablement une arnaque quelque part, les méthodes en question sont utilisées en prod actuellement sur à peu près tout les modèles.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 71 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