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 - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » Tutoriels d'utilisation de gint (commentaires)
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Tutoriels d'utilisation de gint (commentaires)

Posté le 15/07/2017 13:54

Les tutoriels d'utilisation de gint sont sur ce topic.

Pour garder les tutoriels ensemble dans les posts du topic d'origine (et surtout pas créer un topic par tuto...), je vous propose de poster vos questions/commentaires/etc ici. Merci !


Précédente 1, 2, 3, 4, 5, 6, 7, 8 ··· 10 ··· 20 ··· 24, 25, 26 Suivante
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 28/12/2018 09:09 | #


Les fonctions imbriquées ont pas mal de défauts. Je t'en cite quelques-uns :
* Ce n'est supporté que par GCC.
* Tu ne peux pas les utiliser en-dehors de leurs fonctions parentes pour des raisons fondamentales, donc tu ne peux pas les renvoyer.
* Pour les appeler il faut exécuter du code sur la pile, ça ouvre la voie à un vecteur d'attaque classique.

Si tu arrives à utiliser une structure sans que ça soit trop lourd, je pense que c'est plus viable. Et rassure-toi, j'étais debout à minuit pour d'autres raisons.
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 29/12/2018 00:13 | #


Bonsoir, j'ai refait une vraie fonction pour la gestion d'input.
Je te montre tout ça pour avoir un avis sur les possibles améliorations
J'ai créé un type "keyboard_t" pour stocker toutes les données du clavier :
typedef struct { uint8_t k[10];} keyboard_t;

Ensuite la fonction pour enregistrer tout le buffer : tout simplement
void keyboardRead(keyboard_t *kb) {
    volatile uint8_t *p = keyboard_stateBuffer();
    for(int i = 0; i < 10; ++i) kb->k[i] = p[i];
}

Enfin une fonction booléenne qui renvoie vrai si les deux touches en arguments sont poussées (ça gère aussi des cas particuliers):
int inputReader(keyboard_t *kb, key_t k1, key_t k2) {
    if(!k1) k1 = k2;
    if(!k1) {
        for(int i = 0; i < 10; ++i) if(kb->k[i]) return 0;
        return 1;
    }
    if(k1 == k2) k2 = 0;
    //the first digit of k1 is the position in the kb array. We must get it with k1%0x10.
    //the second digit of k1 is the bit position in kb[x] where we can see if the key is down.
    //we get this second digit with k1/0x10. To check if the bit = 1, we shift the whole number by the second digit then we compare it with &1.
    if(
        (( kb->k[k1%0x10] >> (k1/0x10) ) & 1)
        &&
        (!k2 || (( kb->k[k2%0x10] >> (k2/0x10) ) & 1))
    ) return 1;
    return 0;
}


J'ai fait des commentaires en anglais histoire de mon anglais de robot
Comme t'as écrit la biblio t'as peut être fait des outils pour simplifier la tâche

En application cela donne :
void callback_jeu(struct paquet_jeu *pak) {
    keyboard_t clavier;
    gclear();
    //input
    keyboardRead(&clavier);
    if(inputReader(&clavier, KEY_LEFT, KEY_SHIFT)) pak->choix = KICK;
    else if(inputReader(&clavier, KEY_LEFT, 0)) pak->choix = GAUCHE;
    else pak->choix = RIEN;
    //traitement
    switch(pak->choix) {
        case GAUCHE:
            spriteRun(0, 30, &img_jintrun, XJINT, YJINT, JRUNF, &(pak->frame));
            break;
        case KICK:
            spriteRun(0, 30, &img_jintkick, XJINT, YJINT, JKICKF, &(pak->frame));
            break;
        default:
            spriteRun(0, 30, &img_jint, XJINT, YJINT, JIDLEF, &(pak->frame));
    }
    gupdate();
}


Donc tout cela marche
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 29/12/2018 09:51 | #


C'est pas mal, mais alors pas mal du tout !

Je n'ai que des remarques à ajouter pour préciser comment tout cela fonctionne.
keyboard_stateBuffer() renvoie toujours la même adresse, celle d'un tableau qui se comporte exactement comme tu le veux. Tu n'es pas obligé de le copier, par contre comme il change tout seul pendant que tu travailles il faut ajouter volatile devant sinon le compilateur sera confus.
k1/0x10 peut s'écrire k1>>4 et k1%0x10 peut s'écrire k1&0xf. Je pense que GCC est assez intelligent pour l'optimiser donc pas de problème comme ça, mais tu peux te souvenir qu'une division ou un modulo c'est environ 70 cycles processeur, tandis que les décalages et les masques ça se compte en quelques cycles.
Bravo
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 29/12/2018 12:29 | #


Ok super merci pour les conseils Par question de goût je préfère travailler avec une copie complète du clavier, ça servira peut être plus tard

Ajouté le 29/12/2018 à 20:08 :
Salut, cette fois c'est une suggestion pour la biblio. As tu pensé à faire un dimage/gimage qui affiche le sprite en miroir ? Sans une telle fonction ça oblige à cloner ses sprites dans mon cas Même si je vais carrément adapter le game design pour éviter que mon perso tourne la tête
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 29/12/2018 21:44 | #


Eh bien, oui, mais c'est purement et simplement impossible ! Mon format d'images est assez compliqué et optimisé pour effectuer les rendus très (très) vite. Entre autres limitations, tu ne peux pas envisager d'inverser la gauche et la droite. (Tu pourrais, par contre, inverser le haut et le bas, s'il me venait l'idée d'implémenter un truc pareil...)

Je pense qu'avoir plusieurs sprites est une bonne idée pour deux raisons :
* D'abord ça ne coûte pas grand-chose en espace, et tu maintiens des perfs' élevée avec dimage()
* Ensuite, ça t'incite à ajouter de la variation entre les deux côtés de ton personnage

Le premier argument me paraît convaincant pour le programmeur, et le second convaincant pour le game designer, mais je te laisse en juger...
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 01/01/2019 00:21 | #


Rien à voir avec Gint là c'est un problème de C, ce code compile pas :
struct pnj {
    int x;
    perso_t nom;
};

struct map {
    struct pnj pnj[3];
};

struct map map1;
map1.pnj[0].x = 64;
map1.pnj[0].nom = PNJ_VIEUX;
map1.pnj[1].nom = PNJ_RIEN;


et ce bon vieux gcc me dit :
../src/game.c:36:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
map1.pnj[0].x = 64;
     ^
../src/game.c:37:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
map1.pnj[0].nom = PNJ_VIEUX;
     ^
../src/game.c:38:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before '.' token
map1.pnj[1].nom = PNJ_RIEN;


Je ne vois pas du tout le problème
J'ai tenté ça :
struct map map1;
map1.pnj->x = 64;
map1.pnj->nom = PNJ_VIEUX;
(map1.pnj+1)->nom = PNJ_RIEN;

même délire avec le symbole qui manque avant le point. Je comprends pas.
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 01/01/2019 00:28 | #


C'est moi ou tu as mis du code en-dehors d'une fonction ?
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 01/01/2019 12:01 | #


Certes en effet ah ah ah ma crédibilité en prend un coup
Je peux tout expliquer monsieur
(bordel mais n'importe quoi j'en oublie les bases)

Ajouté le 03/01/2019 à 20:12 :
Salut mon cher,
j'essaye de gérer des fichiers avec Bfile sauf que j'ai un drôle de bug... J'ai tout refait simplement avec un petit addin pour voir d'où venait le bug mais impossible de savoir.
Voici le code de l'addin :
#include <display.h>
#include <keyboard.h>
#include <bfile.h>
#include <stdio.h>

#define STORAGE "\\\\fls0\\"
#define SDCARD "\\\\crd0\\"

void strToPath(char *str, uint16_t *fc, char *p) {
    while(*p) *fc++ = *p++;
    while((*fc = *str)) fc++, str++;
}

int main(void)
{
    uint16_t path[15];
    int f, buffer;
    char str[15];
    strToPath("test", path, STORAGE);
    f = BFile_Open(path, BFile_ReadOnly);
    if(f < 0) {
        BFile_Close(f);
        return 0;
    }
    BFile_Read(f, &buffer, sizeof(int), -1);
    BFile_Close(f);
    sprintf(str, "%d", buffer);
    dclear();
    dtext(0, 0, str);
    dupdate();
    getkey();
    return 0;
}


Donc on peut voir que je cherche à voir quel est l'entier qui se cache dans "test", le fichier je le crée avec du vrai C d'ordinateur :
#include <stdio.h>

int main() {
    FILE *f = fopen("test", "wb");
    int a = 25;
    fwrite(&a, sizeof(int), 1, f);
    fclose(f);
    return 0;
}


Donc moi sur la casio, je veux voir "25" sauf que j'ai un sale nombre à la place. Aurais-tu une piste ? Pour info mon fichier fait 4 octets.
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 03/01/2019 20:49 | #


Alors, c'est facile : ton ordinateur est en little-endian alors que la calculatrice est en big-endian. Je peux donc affirmer sans hésiter que le nombre que tu vois à l'écran est 419430400.

Utilise htobe16() et htobe32() de <endian.h> (_DEFAULT_SOURCE) sur ton ordinateur pour convertir en big-endian avant d'écrire la valeur dans le fichier.

Deux trucs pendant que j'y pense :
* N'écris jamais un nombre impair d'octets avec Bfile_WriteFile() ;
* Tu peux utiliser dprint(0, 0, "%d", buffer) si tu veux éviter le sprintf().
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 03/01/2019 21:46 | #


Ah super merci, et t'as bien deviné c'est ce sale nombre qui est affiché. Je compte pas écrire dans des fichiers via la casio mais ça m'intéresse de savoir pourquoi on peut pas écrire par octets impairs
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 03/01/2019 22:04 | #


Ah, l'histoire des écritures de longueur impaire ? C'est une limitation de Bfile que j'ai découverte par hasard, mais qui avait déjà été connue avant. SimLo écrit notamment au sujet du syscall Bfile_WriteFile() :

0x0435: int Bfile_WriteFile_OS( int HANDLE, const void *buf, int size );
SDK Bfile_WriteFile directly calls 0x0435 when HANDLE & 0x0F000000 <> 0
This is true with fls0- or crd0-handles.
0x0435 must not be used to write to a main memory handle!
Never write an odd number of bytes (size). Never use the flash directly as source memory (*buf).

Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 17/01/2019 15:44 | #


Salut cher ami, c'est juste pour quelques précisions sur l'utilisation du timer. Dans la boucle du jeu je dois le stopper pour ouvrir un dialogue, je fais comme ceci :
void talk(perso_t p, char *str, timer_t *timer) {
    char output[40];
    int offset_x, offset_y, i;
    
    timer_stop(timer);
    
    text_configure(&pol_police, color_black);
    
    while(*str) {
        if(*str != '\n') {
            str++; //pour eviter %
            gclear();
            switch(*str) { //detection du perso qui parle
                case 'j':
                    offset_x = 0;
                    offset_y = 35;
                    break;
                case 'p':
                    offset_x = 35;
                    offset_y = 0;
                    break;
                default:
                    gtext(0, 0, "Erreur");
                    gupdate();
                    getkey();
                    return;
            }
        }

        str++;
        i = 0;
        do {
            output[i++] = *(str++);
        } while(*str != '%' && *str != '\n' && *str != '\0');
        output[i] = '\0';
        gimage_part(DWIDTH-TAILLE_AVA, DHEIGHT-TAILLE_AVA, &img_ava, 0, 0, TAILLE_AVA, TAILLE_AVA); //affichage jint
        gimage_part(0, 0, &img_ava, 0, p*TAILLE_AVA, TAILLE_AVA, TAILLE_AVA); //affichage pnj
        gtext(offset_x, offset_y, output);
        gupdate();
        getkey();
    }
    
    timer_start(timer);
}


Comme tu peux le voir, je le réactive à la fin de la fonction, sauf que ça me donne un comportement très étrange du coup je me demande si ça en est la cause avant de me plonger plus profondément sur l'algo.

salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 17/01/2019 16:04 | #


En principe ça doit fonctionner, même si je reconnais que je n'ai pas testé ce cas de figure car dans un jeu je n'aurais pas opté pour l'arrêter.

Essaie avec un cas de test minimal, (type juste stop suivi immédiatement de start), si ça ne marche pas alors il y a un bug à corriger.
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Disperseur Hors ligne Membre Points: 1807 Défis: 1 Message

Citer : Posté le 17/01/2019 17:47 | #


Je ne m'y connais pas trop mais il me semble qu'il est plus simple de programmer avec Gint qu'avec les commandes de base du SDK ? Et puis si je ne m'abuse, il faut quelques connaissances sur le fxSDK pour utiliser Gint ?
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 17/01/2019 18:13 | #


Niveau complexité, aucun n'est plus difficile par principe, mais si on prend en compte l'environnement et la doc, je pense que gint est un peu plus difficile à utiliser : il faut compiler son GCC (sauf Arch Linux), utiliser les outils des Linux en ligne de commande, et me consulter en cas de problème. Le SDK est plus "propre" d'aspect général.

Le fxSDK et gint sont liés d'une façon très forte. Le fxSDK fournit certaines commandes en compilation qui sont appropriées pour développer des add-ins, notamment avec gint. Et surtout, le fxSDK fournit les outils de conversion d'images et de polices qui sont utilisés par gint.

Cela dit le fxSDK est un petit ensemble avec quelques outils et peu d'options, donc on peut à peine parler de "connaissances sur le fxSDK". Il n'y a pas grand-chose à creuser.
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 17/01/2019 18:23 | #


J'ai isolé le problème, je précise que c'est dans la fonction callback que le timer appelle :
timer_stop(pak->timer);
gclear();
gprint(0, 0, "%s", "Ceci est un test");
gupdate();
getkey();
timer_start(pak->timer);

avec ça je peux voir le message et continuer à jouer ensuite. Le problème c'est que dès que je quitte l'addin, la calculette pète des câbles (glitch dans les menu, et crash quand je veux entrer dans une appli) je suis obligé de l'éteindre.
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 17/01/2019 19:22 | #


Eh bien. C'est très dérangeant, on est d'accord. Il faut explorer plusieurs pistes et s'assurer qu'on trouve le problème.

La plus évidente est que tu n'as pas le droit d'appeller getkey() dans un callback, c'est illégal. La raison est que le callback est exécuté pendant la gestion de l'interruption, et donc les interruptions sont coupées, alors que getkey() s'appuie très fort dessus... ça ne peut pas marcher bien à long terme.

Vois le timer handler comme une fonction très rapide qui fait un job simple, met à jour des variables et s'en va. Dessiner à l'écran est acceptable, mais gérer le clavier, c'est vraiment limite.

En plus qu'est-ce que tu penses qu'il va se passer quand tu lances getkey() dans le handler ? Étant donné que ton callback est appelé plusieurs fois par seconde, tu veux que getkey() se lance plusieurs fois « en parallèle » ? Ça n'existe pas : ce qui se passe c'est que ton getkey() bloque tout le reste du programme, y compris l'arrivée de prochaines interruptions.
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Ityt Hors ligne Membre Points: 216 Défis: 0 Message

Citer : Posté le 17/01/2019 20:43 | #


Bah je m'étais dit comme je stop le timer c'est le tapis rouge pour faire ce que je veux Je pense que je vais devoir passer par la structure pak pour sauvegarder l'état du dialogue Je pense que c'est pour le mieux je pourrai avoir le contrôle des fps pendant le dialogue.
salut je m'appelle sacha et je viens du bourg-palette et voici mon meilleur ami pikachu
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 17/01/2019 20:58 | #


Ityt a écrit :
Bah je m'étais dit comme je stop le timer c'est le tapis rouge pour faire ce que je veux

Presque ! Pour dérouler le tapis rouge il faut quand même que tu quittes le callback. C'est peut-être possible en théorie de faire autrement, mais je ne suis pas sûr de vouloir essayer parce que ça pose des problèmes architecturaux un peu subtils...

Je pense que je vais devoir passer par la structure pak pour sauvegarder l'état du dialogue Je pense que c'est pour le mieux je pourrai avoir le contrôle des fps pendant le dialogue.

Je pense que tu peux juste utiliser le callback pour changer des variables qui disent « au prochain frame, lance le dialogue » et le faire dans ton programme principal.
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)


JBerben Invité

Citer : Posté le 13/05/2019 08:38 | # | Fichier joint


I'm really sorry that I can't communicate in French, but I've been following the development of Gint and fxsdk for a little while now. And I'm trying to write a 3D rendering engine in C, but I don't have access to any of the math.h functions. I set up the GCC toolchain with newlib as well, but I can't make sense of how to use newlib's math library rather than Gints', because whenever I #include <math.h>, it always includes Gint's math header file first.

Any help would be much appreciated!
Merci!
Lephenixnoir Hors ligne Administrateur Points: 24069 Défis: 169 Message

Citer : Posté le 13/05/2019 09:16 | #


There's no problem, really! Thanks for your interest in this project.

This behavior is annoying. Since newlib is there now, the next major version of gint (found here because we are migrating the forge, but not production-ready yet) will drop support for whatever standard functions it currently has. Also, all headers are installed in a gint/ directory so that includes are always #include <gint/*.h>.

For now, we can rely on GCC developers who fortunately know this situation can happen, and provide a #include_next directive to include another header with the same name. So you should be able to do:

#include <math.h>  /* Includes gint's version */
#include_next <math.h> /* Includes newlib's version */

Let me know if that works as expected.
Mon graphe (25 Fév): (PythonExtra ; fxsdk#11 ; gint#27 ; (Rogue Life || HH2) ; serial gint ; Boson X ; ...) || (shoutbox v5 ; v5)
Précédente 1, 2, 3, 4, 5, 6, 7, 8 ··· 10 ··· 20 ··· 24, 25, 26 Suivante

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 33 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