π
<-

[Grammer] Programmer en Grammer : La pratique

Regroupement de tous les tutoriaux z80 (82/83/84)

[Grammer] Programmer en Grammer : La pratique

Unread postby Persalteas » 07 May 2013, 09:12

Salut, je vous ai déjà parlé de mon tutoriel Grammer, qui, comme on me l'a fait remarquer, est plus une doc (une très bonne doc) qu'un tuto puisqu'il n'y a pas de partie pratique.

Pour faciliter la tâche, je vais poster ici différentes petites explications censées aider d'éventuels débutants.
Avant tout, je vous conseille de lire la doc. Au moins la survoler. Cliquez sur l'image ci-dessous, et bonne lecture.

Image


I. Généralités pour afficher du texte

Show/Hide spoilerAfficher/Masquer le spoiler
Que serait un langage si on ne pouvait pas afficher de Hello World :p

1) Rappel général sur l'affichage de choses à l'écran:
Comme dit dans le chapitre 9 de la doc, toute commande entrainant une modification de l'écran modifie en fait la zone de la RAM où est stocké l'écran, qu'on appelle buffer.
Donc quand vous faites une commande de dessin (rect, text, horizontal, etc...), ça modifie la zone de la RAM où l'écran est stocké :bj:

Mais ça n'affiche pas sur l'écran ? #stupid#


Eh bien non. Vous devez faire ça à la main, avec une commande qui dit "Appliquer les changements".
Cette commande est DispGraph. Vous devez mettre un dispgraph après des modifications graphiques, pour appliquer vos changements.


Un DispGraph après chaque instruction graphique ? C'est pas un peu lourd ? #stupid#


C'est parce que c'est pas la peine d'en mettre un à toutes les commandes :P En mettre un à la fin de chaque série de modifications du buffer suffit ;)

exemple:
Code: Select all
:.0:
:Rect(...
:Circle(...
:rect('...
:Fill(...
:Text(...
:Dispgraph
:...
:Stop


2) La commande Text

Je vais revenir sur la commande Text qui est... super compliquée. Parce qu'elle a én-or-mé-ment d'options.

Elle permet:
- Un retour automatique à la ligne, et scroll de l'écran automatique
- Un affichage lettre par lettre (type Casio-Basic): /Text(°truc-à-afficher

L'argument "ce-que-la-commande-doit-afficher" peut être:
- Une chaine (encadrée par ses guillemets, au moins un): Text(Y,X,"chaine-à-afficher"
- Un pointeur vers une chaine: Text(Y,X,variable-pointeur
- Un nombre: Text('Y,X,345 (N'oubliez pas la prime avant le Y ! ;) )
- Un nombre enregistré dans une variable-pointeur: Text('Y,X,variable-pointeur ( N'oubliez pas la prime avant le Y ! ;) )
- Une chaine ou un nombre enregistré dans une variable de l'OS: Text(Y,X,Str1
- Un nombre enregistré dans deuxvariables-pointeurs (nombres 32 bits): Text('Y,X,variable-pointeur1variable-pointeur2 (sachant que variable-pointeur2 contient les 16 derniers bits et est une prime (B', C', etc..))

J'ai des problèmes avec mon X !! :'(

Il faut se souvenir que par défaut, les Y se comptes en pixels alors que les X se comptent en colonnes (comme le Output du TI-Basic).
Ainsi, à chaque fois que vous parlez de X à la commande Text, elle voit ça en colonnes. Et encore, parce que le zéro correspond à la première colonne, le 1 à la deuxième, le 2 à la troisième, etc...)

Text(23,4,"helloworld affichera helloworld en Y=23, et en 5ème colonne. (4 représente la 5ème colonne puisque 0 représente la première.)

Heureusement, il est possible de passer en mode X-en-pixels !
OUF ! #beer#

Grâce à l'utilisation de SetFont 2.
SetFont 2 instaure le mode "X-en-pixels", et ainsi, vous pouvez parler avec des X et des Y dans la même unité.
SetFont 0 retourne à la normale.
Il vous suffit de mettre SetFont 2 au début de votre code pour que le mode soit activé pour le reste du programme.

- Les coordonnées enregistrées:

Il faut aussi se souvenir que la commande se souvient des coordonnées où elle a affiché. Elle est donc parfaitement capable de calculer toute seule les coordonnées où elle affichera la prochaine fois. Et c'est ce qu'elle fait, elle a en permanence en mémoire les coordonnées X et Y de la lettre qui sera affichée si on continue à écrire à la suite.

Il est donc possible:
- d'afficher à la suite du dernier texte: Text(°truc-à-afficher
- d'afficher avec un décalage de quelques pixels X et Y: Text(+5,+1,truc-à-afficher (Attention, le X est soit en colonnes soit en pixels selon votre mode SetFont)
- De récupérer les coordonnées enregistrés: Text( (Sans arguments, stocke Y dans Ans et X dans theta'.)

3) REMARQUES GENERALES:
- Plus d'infos dans la Doc
- Un ClrDraw réinitialise les coordonnées enregistrés à 0,0
- Si vous utilisez /Text(, (affichage lettre par lettre) puis Text(° (affichage à la suite du précédent), l'affichage lettre par lettre continue. Vous devrez re-préciser des coordonnées à la main pour revenir en mode normal.
- /Text( a un fonctionnement particulier qui fait qu'elle joue le rôle de DispGraph automatique. Il n'y a donc pas besoin de la faire suivre d'un autre Dispgraph.)
- Il n'est pas possible d'écrire sur un buffer particulier avec Text. Mais on peut se débrouiller en utilisant la commande ° (NOUVEAU !! :bj: ).
- Text(r a le même rôle que /Text(
- Ne rien préciser comme coordonnées signifie utiliser les coordonnées enregistrés. Ainsi, Text(,,"Plop" est la même chose que Text(°"Plop".


4) Contrôle de connaissances :rules:
à quoi correspondent ces différentes formules ?

Text('23,2,E
Affiche en Y=23 et en troisième colonne (eh oui, 0-1-2, 2 est la 3e colonne) le nombre stocké dans la variable-pointeur E.

Text(°r"Plop
Affiche Plop lettre par lettre à la suite du texte précédent.

/Text(12,1,D
Affiche en Y=12, et en deuxième colonne la chaine pointée par la variable-pointeur D.

Text('+3,,34
Affiche 34 à la suite du précédent texte avec un décalage de 3 pixels vers le bas.


ça va, vous êtes pas morts ? ;) ça vous prouve que la syntaxe est peut être bizarre (je reconnais que /Text(',+3,eB' c'est pas très gracieux, mais les multiples possibilités vous montrent que le Grammer est un langage de flemmards avec plein de trucs préprogrammés. Les Axeux payeraient pour avoir le retour automatique à la ligne :lick: (*persalteas runs far away)

Allez, un petit TP ? Par exemple... Un texte qui rebondit sur l'écran.

II. Ne pas s'embêter avec la syntaxe des calculs
Show/Hide spoilerAfficher/Masquer le spoiler
Le Grammer, c'est comme le code de la route, priorité à droite. Si vous êtes arabe ou asiatique et que vous avez l'habitude de lire en partant de la droite, vous pouvez sauter cette section. (Ou si vous avez l'habitude de la notation dite "RPN", la notation polonaise inverse)

Donc. Juste après deux remarques méga-importantes, nous allons prendre des suites d'opérations au hasard, et apprendre à les mettre en Grammer.
- LES PARENTHESES NE SERVENT PAS A EXPRIMER UNE PRIORITE, mais à lire un octet pointé par un pointeur.
- les multiplications ne sont pas automatiques, LA PRESENCE DU SIGNE "x" EST OBLIGATOIRE.
:rules:

Par exemple: 3-5+4/2+(3xA) désigne La valeur stockée à l'adresse 3xA à laquelle on ajoute 2 pour diviser 4, à laquelle on ajoute 5 pour la soustraire à 3. Et comme ça va être très probablement négatif, on va se retrouver avec un résultat dans les 65000 et quelques.
Aow. shocking. :~o

C'est pas la valeur que vous vouliez, hein ?
Alors oui, c'est compliqué. ;) Mais pas insurmontable . :bj:

1) Exemple de "conversion de calculs"
Prenons notre calcul.
3-5+4/2+(3xA)
Ce qu'on veut, c'est prendre 3, lui enlever 5, lui ajouter 4/2, et enfin lui ajouter la valeur située à l'adresse 3xA.

Souvenons nous de deux choses:
- Le programme lit les lignes d'instructions de gauche à droite, mais il lit les instructions de droite à gauche.
- quand on ne précise pas le premier facteur/terme/numérateur d'une opération, c'est Ans qui est utilisé.

Donc nous allons utiliser Ans.
Code: Select all
:3-5   //Prenons 3 et enlevons lui 5.
:+4/2   // Ajoutons à Ans 4/2 (le calcul est lu de droite à gauche, donc la multiplication est faite avant l'addition).
:+(3xA   //Là aussi, le programme commence par calculer 3xA, puis lit l'octet situé à cette adresse quand il voit la parenthèse, et enfin lui ajoute Ans.

Et hop, ai-je envie de dire. C'était si difficile ?

Et ça fonctionne pareil pour les tests boléens.
3xA-1 or Pxltest(20,34) xor B
Code: Select all
:3xA
:-1
: or Pxltest(20,34
: xor B


Mais...Mais...Mais C'est affreusement long ! :bang: Et si je veux mettre 3xA-1 ou Pxltest(20,34) xor B dans une condition If, comment je fais avec plusieurs lignes pour une seule condition ? :s:


Et Dieu créa le symbole deux-points.
En effet, les condition If, et plus globalement les 3/4 des fonctions ne reconnaissent comme nouvelle ligne que le token original deux-points qu'on crée en appuyant sur [enter]. Ainsi, vous pouvez utiliser le token deux points [2nd][.] autant de fois que vous voulez pour séparer vos calculs, le If considérera qu'on a toujours pas changé de ligne.

Démonstration. Ouvrez grands vos yeux. Regardez le professionnel.
If 3xA-1 or Pxltest(20,34) xor B
devient:
Code: Select all
:If 3xA:-1: or Pxltest(20,34: xor B
:code à appliquer si la condition est vraie...


Compris ? ;)

Mouais, c'est quand même pas super pratique pour se repérer... On a vite fait de perdre le fil. :|

Et Xeda créa le token espace.
Devinez quoi ? il a exactement le même rôle que le deux points, sauf que c'est nettement plus propre !
Code: Select all
:If 3xA -1  or Pxltest(20,34  xor B
:code à appliquer si la condition est vraie...


:#tritop#: Like a boss ! :#tritop#:


Des questions ? :comprends_po:

III. Utiliser les appvars
Show/Hide spoilerAfficher/Masquer le spoiler
Salut les copains. Si vous lisez cette troisième partie c'est que ça vous plait, et j'en suis très flatté :#vive#:
Ici, je vais vous apprendre à enregistrer des données, que ce soit des données stockées pour le fonctionnement du programme (par exemple du stockage de graphismes) ou des données modifiables (par exemple un highscore enregistré...)

Vous remarquez que contrairement au TI-Basic, l'utilisation des listes est plutôt difficile (même si elle reste possible). On va donc utiliser des Appvars qui vont fonctionner pareil, ou presque.

:#fou2#: Des AppVars ? ça se mange ?

Oui, mais justement, c'est pas super bon, parce qu'une appvar, c'est rachitique. C'est pas du tout grassouillet. Et c'est bien pour ça qu'on les choisit: c'est une forme de stockage qui prend pas beaucoup d'octets, et qui ne dérange pas l'utilisateur.

Allez les enfants, en rang deux par deux, on y va. :#zen#:

1) Créer une Appvar pour servir de liste, ou de stockage modifiable de données:
Nous allons utiliser pour ça notre commande tout-faite built-in interne tout ça, c'est pas comme si on était en assembleur à bidouiller la VAT, toussa... J'ai nommé, j'ai nommé, applaudissez la bien fort, MakeVar( !

MakeVar sert à créer des variables de l'OS. Une Appvar est une variable de l'OS. Quelle coïncidence.
pour créer votre Appvar, vous devez savoir:
- la taille que vous voulez lui donner (je vais choisir pour cet exemple 10 octets)
- le nom que vous voulez lui donner (je vais choisir pour cet exemple "tiplanet" )

La lettre de type des Appvars étant le U, je créerai mon appvar avec MakeVar(10,"Utiplanet
.
Si vous n'êtes pas cimmérien, ça devrait vous avoir créé une appvar, avec dix octets de zéros dedans.
Nous verrons ensuite comment lire et écrire dans cette appvar.

2) Créer une Appvar de stockage de données hexa (des codes de sprites par exemple):
Je considère que, comme moi, vous êtes des flemmards, et que vous faites vos sprites non pas à la main/de tête mais avec un convertisseur de sprites sur PC où sur calculatrice. (Je connais notamment TokenIDE sur PC et Spritetohex sur calc.)

étape 1: créer et compiler le programme source
Créez un programme, entrez la commande AsmPrgm sur la première ligne puis vos codes hexa tous mis bout à bout sur la deuxième.
Code: Select all
:AsmPrgm
:08081C3E1C7F3E7EFF7EFF7EFF3C ... ... 1818043408FF99FF99FF08101C181E181D

Il faut vous souvenir tout de même de la taille en octets de chaque sprite pour pouvoir les retrouver après, notez le vous sur une feuille à coté.

Envoyez ensuite ce 8xp à votre TI, et compilez le:
Code: Select all
AsmComp(prgmSOURCE,prgmSOURCE2


étape 2: transformez votre programme en Appvar
Vous savez faire des copier-coller en Grammer ? C'est avec la commande Misc.
Code: Select all
Misc(0,"ESOURCE2","Utiplanet",taille de l'Appvar,2

Pourquoi E et U ? Ce sont les lettres de type, E pour programme et U pour appvar, indiquant à partir de quoi vous copiez et dans quoi.
Taille de l'Appvar: La taille en octets que pèsera votre appvar, c'est à dire la somme des poids de chacun de vos codes de sprites. (si j'ai 3 sprites de 8 octets et 2 de 32 octets, ce sera 88 octets.)
Pourquoi 2 ? Moi même je n'en suis pas certain... En fait, on demande au programme de commencer à copier en sautant deux octets au début du programme SOURCE2. Ces deux octets correspondent peut-être au token "AsmPrgm", mais je n'en suis pas certain, mais de toutes façons on en a pas besoin dans notre Appvar.

Si l'appvar tiplanet existait déjà le contenu est remplacé. Sinon elle est créée directement avec le contenu copié. Ans contiendra un pointeur vers la nouvelle variable, et Ɵ' la taille de cette nouvelle variable (en octets).

Maintenant que vous avez votre belle Appvar, vous pouvez supprimer les programmes sources et autres trucs inutiles.

étape 3: retrouver des pointeurs vers nos sprites
C'est quand même ça le but ! =P Faire des dessins, comme des gosses de maternelle ! Quand je vous dis que c'est facile, le Grammer !

Il faut déjà trouver le pointeur vers le début de l'appvar.
Comme par hasard y'a une fonction faite pour ça :P Ce que la nature est bien faite quand même ! :bj:
FindVar("Utiplanet va nous donner un pointeur sur l'appvar, donc sur le début du premier sprite. Vous pouvez stocker ça dans une variable pointeur pour l'avoir sous la main.
Code: Select all
FindVar("Utiplanet"→A


Et pour les autres sprites ? :s:

Vous ressortez votre feuille de papier. Et avez la taille de vos sprites, vous faites des additions pour retrouver les suivants. C'est partie pour la théorie.

exemple, sur ma feuille à moi y'avait écrit:
sprite1: 8 octets
sprite2: 8 octets
sprite3: 8 octets
sprite4: 32 octets
sprite5: 32 octets


donc j'ai mon pointeur A que j'ai trouvé avec FindVar:
Code: Select all
:FindVar("Utiplanet"→A
:+8→B
:+8→C
:+8→D
:+32→E


le sprite1 est stocké de l'adresse A à l'adresse A+7 (8 octets.)
le sprite2 est stocké de l'adresse A+8 à l'adresse A+8+7 (8 octets.)
le sprite3 est stocké de l'adresse A+8+8 à l'adresse A+8+8+7 (8 octets.)
le sprite4 est stocké de l'adresse A+8+8+8 à l'adresse A+8+8+8+31 (32 octets)
le sprite5 est stocké de l'adresse A+8+8+8+32 à l'adresse A+8+8+8+32+31 (32 octets).
et à l'adresse A+8+8+8+32+31, l'appvar est terminée. ça alors. ;)

Or, comme par hasard, B=A+8, C=A+8+8, D=A+8+8+8, E=A+8+8+8+32. On a donc bien 5 pointeurs A,B,C,D et E sur nos 5 sprites.

j'ai rien compris. C'est grave ? :~|


Non. Contentez vous de retenir la marche à suivre, à savoir:
:Findvar("Utiplanet"→A+8→B+8→C+8→D+32→E
Vous aurez vos 5 pointeurs.


IV. Des petits TP...

Alors, numéro 1, un cercle qui rebondit sur les parois de l'écran.
Réponse:
Show/Hide spoilerAfficher/Masquer le spoiler
Image
Code: Select all
.0:Return
(:Full)
:9→X→Y
:1→B→C
:Repeat getKey(15
:Circle(Y,X,9,1
:DispGraph
:ClrDraw
:X+B→X
:If >85  or X<9
:-B→B
:Y+C→Y
:If >54  or Y<9
:-C→C
:End
:Stop


Deuxio.. un curseur carré noir, qui dessine en grayscale quand on appuie sur [enter] et qui efface quand on appuie sur [del]
Réponse:
Show/Hide spoilerAfficher/Masquer le spoiler
ça devient serré, je vais commenter un peu :P Si quoi que ce soit pose un problème, demandez !

Image
Code: Select all
:.0:
:pi9872→P   // permet de stocker l'adresse 9872(hex) dans P
:ClrDrawP    // efface le buffer commençant à l'adresse P
:SetBuf(°P  // définit le buffer commençant à l'adresse P comme buffer de grayscale
:Lbl "A→Z   // Met l'adresse du label A dans Z
:0→X→Y
:Repeat getKey(15
:Repeat 1   // permet de ne répéter la boucle qu'une seule fois
:DispGraph
:call Z        //appelle la subroutine à l'adresse Z (soit le label A)
:getKey(56  //teste si [del]est pressée
:If +getKey(9    //permet de tester à la fois Ans (getkey(56)) et getkey(9), donc "si [del] où [enter] sont pressées"
:Rect(X,Y,6,6,1-getKey(56    //dessine un rectangle blanc si [del] est pressée, noir sinon (sur le buffer normal, 50%)
:X+getKey(3 -getKey(2→X    // déplacement du curseur (attention à l'espace)
:Y+getKey(1 -getKey(4→Y    // déplacement du curseur (attention à l'espace)
:End          //fin de la boucle
:Stop
:.A                       //label A, qui commence une subroutine
:Rect(X,Y,6,6,2,P   //Dessine un rectangle plein inversé de 6x6 sur le buffer de P (50%)
:Rect(X,Y,6,6,2     //Dessine un rectangle plein inversé de 6x6 sur le buffer normal (les 50% restants, on obtient bien du noir)
:End                    //fin de la subroutine


Allez, c'est la récré, allez jouer. N'hésitez pas a poster vos questions sur le forum, ainsi que vos programmes, mêmes s'ils sont inutiles, ils peuvent aider d'autres débutants à comprendre. :bj:

A bientôt pour un chapitre sur euh... le grayscale ? ou autre ?
Vous avez des idées ?


PS: pour ceux qui auraient fui devant ces explications... méheu... les copains... restez, quoi...
Nan mais sérieux, le Grammer ça déchire sa race wesh, faut pas vous tirer...
User avatar
PersalteasMembre UPECS
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 6.2%
 
Posts: 2337
Images: 113
Joined: 04 Feb 2010, 00:00
Location: Evry (France)
Gender: Male
Calculator(s):
MyCalcs profile
Class: PhD candidate, Bioinformatics

Return to Tutoriaux

Who is online

Users browsing this forum: ClaudeBot [spider] and 5 guests

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
874 utilisateurs:
>851 invités
>16 membres
>7 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)