Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » gint : un noyau pour développer des add-ins
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

gint : un noyau pour développer des add-ins

Posté le 20/02/2015 17:30

Ce topic fait partie de la série de topics du fxSDK.

En plus des options de programmation intégrée comme le Basic Casio ou Python, la plupart des calculatrices Casio supportent des add-ins, des programmes natifs très polyvalents avec d'excellentes performances. Les add-ins sont généralement programmés en C/C++ avec l'aide d'un ensemble d'outils appelé SDK.

Plusieurs SDK ont été utilisés par la communauté avec le temps. D'abord le fx-9860G SDK de Casio avec fxlib pour Graph monochromes (plus maintenu depuis longtemps). Puis le PrizmSDK avec libfxcg pour Prizm et Graph 90+E (encore un peu actif sur Cemetech). Et plus récemment celui que je maintiens, le fxSDK, dont gint est le composant principal.

gint est un unikernel, ce qui veut dire qu'il embarque essentiellement un OS indépendant dans les add-ins au lieu d'utiliser les fonctions de l'OS de Casio. Ça lui permet beaucoup de finesse sur le contrôle du matériel, notamment la mémoire, le clavier, l'écran et les horloges ; mais aussi de meilleures performances sur le dessin, les drivers et la gestion des interruptions, plus des choses entièrement nouvelles comme le moteur de gris sur Graph monochromes.

Les sources de gint sont sur la forge de Planète Casio : dépôt Gitea Lephenixnoir/gint

Aperçu des fonctionnalités

Les fonctionnalités phares de gint (avec le fxSDK) incluent :

  • Toutes vos images et polices converties automatiquement depuis le PNG, sans code à copier (via fxconv)
  • Un contrôle détaillé du clavier, avec un GetKey() personnalisable et un système d'événements à la SDL
  • Une bibliothèque standard C plus fournie que celle de Casio (voir fxlibc), même un peu de C++ (voir µSTL)
  • Plein de raccourcis pratiques, comme pour afficher la valeur d'une variable : dprint(1,1,"x=%d",x)
  • Des fonctions de dessin, d'images et de texte optimisées à la main et super rapides, surtout sur Graph 90+E
  • Des timers très précis (60 ns / 30 µs selon les cas, au lieu des 25 ms de l'OS), indispensables pour les jeux
  • Captures d'écran et capture vidéo des add-ins par USB, en temps réel (via fxlink)

Avec quelques mentions spéciales sur les Graph monochromes :
Un moteur de gris pour faire des jeux en 4 couleurs !
La compatibilité SH3, SH4 et Graph 35+E II, avec un seul fichier g1a
Une API Unix/POSIX et standard C pour accéder au système de fichiers (Graph 35+E II seulement)

Et quelques mentions spéciales sur les Graph 90+E :
Une nouvelle police de texte, plus lisible et économe en espace
Le dessin en plein écran, sans les bordures blanches et la barre de statut !
Un driver écran capable de triple-buffering
Une API Unix/POSIX et standard C pour accéder au système de fichiers

Galerie d'add-ins et de photos

Voici quelques photos et add-ins réalisés avec gint au cours des années !



Arena (2016)Plague (2021)



Rogue Life (2021)



Momento (2021)



Communication avec le PC (cliquez pour agrandir)


Utiliser gint pour développer des add-ins

Les instructions pour installer et utiliser gint sont données dans les divers tutoriels recensés dans le topic du fxSDK. Il y a différentes méthodes de la plus automatique (GiteaPC) à la plus manuelle (compilation/installation de chaque dépôt). Le fxSDK est compatible avec Linux, Mac OS, et marche aussi sous Windows avec l'aide de WSL, donc normalement tout le monde est couvert

Notez en particulier qu'il y a des tutoriels de développement qui couvrent les bases ; tout le reste est expliqué dans les en-têtes (fichiers .h) de la bibliothèque que vous pouvez consulter en ligne, ou dans les ajouts aux changelogs ci-dessous.

Changelog et informations techniques

Pour tester les fonctionnalités et la compatibilité de gint, j'utilise un add-in de test appelé gintctl (dépôt Gitea Lephenixnoir/gintctl). Il contient aussi une poignée d'utilitaires d'ordre général.

Ci-dessous se trouve la liste des posts indiquant les nouvelles versions de gint, et des liens vers des instructions/tutoriels supplémentaires qui accompagnent ces versions.

VersionDateInfos supplémentaires
gint 2.8.017 Mai 2022Effets dynamiques sur les imagesAPI de manipulations d'images
Overclock intégré
gint 2.7.119 Mars 2022Tutoriel capture des flux standards
gint 2.7.031 Décembre 2021
gint 2.6.029 Août 2021Tutoriel de capture vidéo par USB
gint 2.5.28 Juin 2021
gint 2.5.12 Juin 2021
gint 2.5.026 Mai 2021Intégration de fxlibc (dépôt) — Tutoriel de communication par USB
gint 2.4.027 Avril 2021Api GINT_CALL() pour les callbacks
gint 2.3.12 Février 2021
gint 2.3.029 Janvier 2021
gint 2.2.112 Janvier 2021
gint 2.2.011 Janvier 2021
gint 2.1.116 Septembre 2020
gint 2.1.021 Août 2020Polices UnicodeNouvelle API du moteur de gris
gint 2.0.3-beta10 Juillet 2020Modifications de l'API timer
gint 2.0.2-beta17 Juin 2020
gint 2.0.1-beta1er Juin 2020

Anecdotes et bugs pétés

Ô amateurs de bas niveau, j'espère que vous ne tomberez pas dans les mêmes pièges que moi.


TODO list pour les prochaines versions (2022-05-15)

gint 2.9
  1. Changements de contextes CPU. À reprendre du prototype de threading de Yatis pour permettre l'implémentation d'un véritable ordonnanceur. Demandé par si pour faire du threading Java. Je vais peut-être coder des effets algébriques pour m'amuser un peu.
  2. Fignoler le driver USB. Ajouter la communication PC→calto, des pipes interruption/isochrones. Ajouter le support de descripteurs de fichiers USB. Potentiellement pousser jusqu'à avoir GDB pour debugger.

Non classé

  • Support de scanf() dans la fxlibc.
  • Regarder du côté serial (plus facile que l'USB) pour la communication inter-calculatrices (multijoueur) et ultimement l'audio (libsnd de TSWilliamson).
  • Un système pour recompiler des add-ins mono sur la Graph 90+E avec une adaptation automatique.
  • Support des fichiers en RAM pour pouvoir utiliser l'API haut-niveau sur tous les modèles et éviter la lenteur de BFile à l'écriture quand on a assez de RAM.



Précédente 1, 2, 3 ··· 10 ··· 20 ··· 30 ··· 40 ··· 50 ··· 60 ··· 65, 66, 67, 68, 69 Suivante
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 28/06/2022 13:01 | #


Tu peux émuler ce comportement en lisant les événements à chaque frame de ton toolkit. Pour avoir le mapping des KeyPressed et KeyReleased, vide simplement les tableaux, puis marque les changements pour chaque événement que tu vois passer.
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 28/06/2022 13:31 | #


Ok vous m'avez perdu. Juste Lephé' (ou quelqu'un d'autre qui comprend) tu peux m'expliquer comment fonctionnent les évènements clavier dans gint ? De ce que j'ai compris : quand on appuie sur une touche, ça ajoute un "key event" à la "key event queue" ; mais ce que j'ai pas compris, c'est quand est-ce que gint lit ces évènements/les utilise ?
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 28/06/2022 13:34 | #


C'est ça. Les événements sont sortis de la file quand tu utilises pollevent() ou waitevent(). C'est la méthode canonique pour accéder à l'information de ce qui se passe sur le clavier. getkey() le fait aussi indirectement.

keydown() n'est qu'une information secondaire qui te rappelle le dernier état de la touche dont tu as été informé par un événement.
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 28/06/2022 13:37 | #


Ah okéééé. Donc certaines fonctions sortent des évènements de la file, et d'autres renvoient des infos selon le dernier évènement sorti lié à une touche spécifique.

Et est-ce que gint sort un/des évènements dans la boucle main de mon programme ?
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 28/06/2022 13:43 | #


C'est ça. Le driver clavier ne sort jamais les événements tout seul; d'ailleurs, pour différentes raisons théoriques, il est impossible de savoir si ton programme a une boucle principale et où elle est.

Les événements sont des informations qui vous sont destinées, et que vous pouvez lire avec pollevent() et waitevent(). Vous n'avez pas trop le choix, d'ailleurs, parce qu'au bout d'un moment la file se remplit et vous perdez des informations si elle est pleine.

getkey() défile aussi les événements, actuellement c'est la seule fonction qui le fait. Mais comme tout le monde est synchronisé sur la même source d'événements, il est possible de combiner plusieurs fonctions si on fait un peu attention, ce qui n'est pas possible si certaines fonctions lisent l'état instantané du clavier.
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 28/06/2022 13:47 | #


Ah ok donc en fait gint ajoute des évènements au fur et à mesure que des touches sont pressées (déolé je résume pour moi-même) mais ne les sort pas de la file (enfin je suppose qu'il y a une taille maximale de ladite file), et on peut les sortir de la file nous-mêmes, et d'ailleurs si on le fait pas c'est pas bien parce qu'on en a trop !
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Slyvtt Hors ligne Community Manager Points: 801 Défis: 0 Message

Citer : Posté le 28/06/2022 14:00 | #


J'ai pas regardé, mais j'imagine qu'il y a un système de "rolling" qui vire les plus anciens évènements qui n'ont pas été traités quand la liste est pleine pour mettre les nouveaux à la place en bout de liste.
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 28/06/2022 14:07 | #


C'est ça Zecter !

Et pour SlytVTT, non si la file est pleine les événements sont perdus. C'est fait intelligemment donc même dans ce cas tu seras toujours synchronisé avec l'état du clavier une fois tout les événements lus. Mais parfois une touche aura été pressée puis relâchée, ou l'inverse, et tu n'en seras pas informé.
Slyvtt Hors ligne Community Manager Points: 801 Défis: 0 Message

Citer : Posté le 28/06/2022 14:21 | #


Quand tu dis les évènements sont perdus, tu parles des événements les plus récents, ceux arrivés une fois la file pleine ? C'est bien cela ?
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 28/06/2022 14:23 | #


C'est ça. La structure keydev a un compteur d'événements perdus si jamais ça te pose question et tu veux vérifier dans un add-in si ça arrive. Mais en pratique on est loin de la taille sauf si l'application est vraiment lente. C'est dur pour l'utilisateur de presser, relâcher ou maintenir plusieurs dizaines de touches en 1/128ème de seconde
Slyvtt Hors ligne Community Manager Points: 801 Défis: 0 Message

Citer : Posté le 28/06/2022 16:09 | #


En fait c'est surtout pour comprendre au mieux la tripaille interne, quand on connaît mieux, on utilise mieux (du moins a priori )
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 28/06/2022 16:47 | #


Oui voilà c'est surtout pour ça que je pose des questions !
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 02/07/2022 12:56 | # | Fichier joint


Bon allez je pose ma question.
Je suis sur 90+E et je suis en train d'essayer de faire un Snake tout ce qu'il y a de plus simple. J'ai dessiné une tilesheet de 16x16 (fichier joint) (et aussi une autre de 32x32 mais c'est trop grand sur la calculatrice) et j'essaye maintenant de dessiner mon snake sur l'écran. Je suis débutant en C donc bon, mais je comprends les bases. Voilà mon code :
render.h
#ifndef _SNAKE_RENDER_H
#define _SNAKE_RENDER_H

struct snake {
    int dir;
    int length = 3;
    int hx, hy; //position de la tête
    int body[length][2]; //contient des paires de coordonnées (tête non incluse)
};

void draw_snake(struct snake const snake);

#endif /* _SNAKE_RENDER_H */

render.c
#include <gint/display.h>
#include <gint/image.h>
#include "render.h"

void draw_snake(struct snake const snake) {
    extern bopti_image_t img_tilesheet16;
    //extern bopti_image_t img_tilesheet32;
    
    dsubimage(snake.hx * 16, snake.hy * 16, &img_tilesheet16, 0, 0, 16, 16, DIMAGE_NONE);
}

Y'a rien dans mon main.c, à part un #include "render.h".

Je veux pouvoir dessiner chaque partie de mon Snake orientée dans la bonne direction. J'ai déjà du code pour trouver la direction sur lequel me baser, je voulais juste de l'aide sur l'utilisation de image.h pour faire des rotations.

Merci d'avance !
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 02/07/2022 13:57 | #


C'est un bon début !

struct snake {
    int dir;
    int length = 3;
    int hx, hy; //position de la tête
    int body[length][2]; //contient des paires de coordonnées (tête non incluse)
};

Tu ne peux pas avoir int body[length][2] - c'est "trop puissant". C'est parce que la longueur d'un tableau fait partie du type ; par exemple, int x[2] et int x[3] ne sont pas du même type. En écrivant int body[length][2], tu demandes à ce que le type de body change selon la valeur que tu mets dans length à l'exécution. Et ça ce n'est pas autorisé, parce que le langage C impose que les types soient fixés dès que tu écris le code (à la compilation).

Si tu veux tout savoir ça s'appelle un type dépendant (plus détaillé). Et le langage C n'a pas de types dépendants

Et sinon, tu ne peux pas donner une valeur par défaut à length comme ceci. Peut-être que ça t'a échappé, mais quand tu écris struct snake { ... } ça ne définit pas une nouvelle variable, à la place ça définit un nouveau type et ensuite il faut encore que tu crée la variable :

struct snake {
   ...;
};

int main(void)
{
    int x = 2;
    struct snake the_snake;
    struct snake other_snake = { .length = 3 };
}

Tu peux voir ci-dessus la syntaxe pour initialiser le membre length à 3 lors de la déclaration de la variable. Tu ne peux cependant pas forcer une valeur par défaut au moment où tu écris le bloc struct snake { ... }.

Pour faire simple avec body je te suggère de juste avoir une taille maximale, eg. 100, de déclarer int body[100][2], et ensuite de faire attention que le serpent ne devienne juste pas plus long que 100 blocs

Je veux pouvoir dessiner chaque partie de mon Snake orientée dans la bonne direction. J'ai déjà du code pour trouver la direction sur lequel me baser, je voulais juste de l'aide sur l'utilisation de image.h pour faire des rotations.

Alors ça va être un peu rude. Pour faire simple je te suggère de juste avoir 4 images avec chaque direction. Mais si tu veux la solution dynamique, voilà comment ça marche. Faisons ça sous la forme d'une fonction (assez lente mais on s'en fout) qui marche comme dsubimage() mais rajoute un paramètre de direction tout à la fin :

#include <image.h>
#include <gint/display.h>

// direction: 0=up, 1=right, 2=down, 3=left
void dsubimage_rotated(int x, int y, image_t *img, int left, int top, int width, int height, int flags, int direction)
{

Les fonctions de <image.h> vont allouer la nouvelle image en même temps qu'elles transforment, donc on peut tout de suite commencer à transformer. Notre image d'entrée (qui doit être en P8 ou RGB565, <image.h> ne permet pas de transformer le P4) est la sous-section spécifiée en paramètre :

    image_t sub;
    image_sub(img, left, top, width, height, &sub);

Je n'ai pas programmé les rotations par 90/180/270 degrés explicitement encore, donc on va utiliser la fonction de rotation générique image_rotate() qui génère une "transformation linéaire" :

    // angle de rotation pour chaque direction (radians)
    static float angles[4] = { 0, -1.570796, 3.141593, 1.570796 };

    // la "transformation linéaire" contient les détails de la rotation
    struct image_linear_map map;

    // générer les détails pour notre image et notre angle
    image_rotate(sub, angles[direction], false, &map);

Ensuite on peut utiliser image_linear_alloc() qui crée une copie de la sous-image et applique la rotation :

    image_t *rotated = image_linear_alloc(sub, &map);

Et enfin on peut faire le dessin :

    dimage(x, y, rotated);

On n'oublie pas de libérer les images allouées dynamiquement à la fin :

    image_free(rotated);
}

(Je n'ai pas testé.) Je suis pas sûr que ça te parle parce que c'est relativement compliqué, mais au moins c'est là. ^^"
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 03/07/2022 11:48 | #


Ok pour la partie de body à propos de length et les types dépendants. Je programme en Python et Java et je me suis dit qu'on pouvait modifier la taille des arrays en C aussi. Pour l'initialisation de length à 3 ouais ok j'étais pas sûr.

Pour la partie rotation d'image, je pense que je vais faire comme tu m'as dit (quatre images différentes pour chaque direction). Je comprend généralement ton code mais y'a quelques trucs que je comprends pas :
- Peux-tu m'expliquer l'utilisation de pointeurs au lieu de variables ? (image_t *img, image_t sub, ...) ?
- J'ai oublié les autres questions mais voilà.

Merci !
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 03/07/2022 11:52 | #


- Peux-tu m'expliquer l'utilisation de pointeurs au lieu de variables ? (image_t *img, image_t sub, ...) ?

De façon générale on utilise des pointeurs. Si tu passais un image_t à dsubimage(), ton programme serait obligé de copier la structure entière pour rien, ce qui serait assez lent. En passant un pointeur (qui est un tout petit objet), on évite du brassage mémoire inutile. A moins que tu aies des structures toutes petites (eg. deux int), le réflexe c'est toujours de passer les structures par adresse.

Je ne l'ai pas mentionné pour ne pas en faire des tartines, mais ton code a le même problème : tu dupliques ton serpent entier à chaque appel de fonction !

Pour ce qui est de image_t sub, là par contre je suis vraiment en train de créer une nouvelle variable, et pour ça je peux soit l'allouer sur la pile (comme je l'ai fait) soit utiliser malloc(). La première option est plus simple
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 03/07/2022 12:26 | #


Aaaaaaaah okééééééé !!!!! Donc quand on passe une structure en argument dans une fonction, le compilateur la duplique. Dans ce cas-là je vois pourquoi les pointeurs sont mieux. Donc si je repasse à travers ton code, ça donne ça :
- Création d'une nouvelle variable de type image_t qui contiendra la sous-image, et juste après on lui donne la sous-image (en passant la localisation de la variable en mémoire dans la fonction : &sub)
- Création d'une structure map qui contiendra les détails de notre image tournée, et juste après on lui donne les détails (fonction image_rotate) (toujours l'utilisation de localisation physique dans la mémoire : &map, mais pas pour sub ?)
- Création d'un pointeur qui contient notre image tournée
- Dessin de l'image
- Libération de l'espace mémoire utilisé par l'image tournée

(Je viens de remarquer que tu as fait en sorte qu'on puisse passer des structures autant que des pointeurs dans la majorité de tes fonctions !)
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 03/07/2022 12:41 | #


- Création d'une nouvelle variable de type image_t qui contiendra la sous-image, et juste après on lui donne la sous-image (en passant la localisation de la variable en mémoire dans la fonction : &sub)

Passer &sub par adresse comme ceci permet à la fonction image_sub() de la modifier ; en gros ça revient à initialiser sub avec le résultat de image_sub() ; si je renvoyais un image_t on aurait le même problème de duplication. C'est un autre idiome classique.

- Création d'une structure map qui contiendra les détails de notre image tournée, et juste après on lui donne les détails (fonction image_rotate) (toujours l'utilisation de localisation physique dans la mémoire : &map, mais pas pour sub ?)

L'objet map contient juste quelques coefficients numériques. image_linear() permet de faire pas mal d'opérations (rotations + miroirs + agrandissement), et map spécifie ce qu'on veut exactement (rotation de 90°). Ici comme pour &sub, je passe &map ce qui revient à dire que j'initialise map avec le résultat de image_rotate().

- Création d'un pointeur qui contient notre image tournée

Oui ou plus spécifiquement allocation et rotation de la nouvelle image, et à la fin on récupère un pointeur qui mène au résultat.

T'as tout juste

(Je viens de remarquer que tu as fait en sorte qu'on puisse passer des structures autant que des pointeurs dans la majorité de tes fonctions !)

Comment ça ?
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 03/07/2022 12:57 | #


T'as tout juste

YOUPI !!!
Comment ça ?

Bah on peut passer des pointeur OU des structures en paramètres dans la majorité des fonctions, et le résultat sera le même (par exemple l'histoire de &sub et &map). Non ?
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Lephenixnoir Hors ligne Administrateur Points: 22452 Défis: 149 Message

Citer : Posté le 03/07/2022 12:58 | #


Non, le prototype indique soit une structure, soit un pointeur vers une structure, mais jamais les deux à la fois. En dans l'immense majorité des cas, c'est obligatoirement un pointeur.
Zecter Hors ligne Membre Points: 155 Défis: 0 Message

Citer : Posté le 03/07/2022 12:59 | #


Ah ok c'est juste moi qui imagine des trucs . Ok j'y penserai dans le futur.

Merci pour tout !
Oui.

Langages appris (pas tous complètement)
Cliquer pour enrouler
- Python
- Java
- Basic Casio
- C


J'ai une Casio Graph 90+E.

Ma citation favorite
Cliquer pour enrouler
« La théorie, c'est quand on sait tout et que rien ne fonctionne.
La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi.
Ici, nous avons réuni théorie et pratique :
Rien ne fonctionne... et personne ne sait pourquoi ! »
- Albert Einstein


Remerciemembres
Précédente 1, 2, 3 ··· 10 ··· 20 ··· 30 ··· 40 ··· 50 ··· 60 ··· 65, 66, 67, 68, 69 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 v42 © créé par Neuronix et Muelsaco 2004 - 2022 | Il y a 32 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