330

[un peu HS]J'ai lu quelques posts plus haut que tu avais un problème avec le texte caché. Perso j'avais fait un lecteur qui fonctionnait ligne par ligne (comme le votre) et j'avais une petite astuce. Dans l'en-tête de chaque ligne on a:
Position x, fonte, gras, italique, soulignement, couleur, hauteur
Si on veut changer de format en cours de ligne (ou insérer une expression, une image, etc.) il suffit de mettre sa hauteur à 0, ainsi le lecteur continuera sur la ligne d'en-dessous en utilisant la position x précalculée (ce qui est utile pour revenir en arrière).
Et là où ça a un rapport avec le sujet (eh oui!) c'est que si seul un bout de la ligne est cachée, il suffit de lui donner une ligne supplémentaire avec l'attribut caché. Normalement il n'y aurait aucun problème (une ligne avec caché=1 est carrément sautée, où qu'elle soit)... Parce que tu utilises quelle méthode pour le moment Raphaël?[un peu HS]
avatar
Highway Runners, mon jeu de racing à la Outrun qu'il est sorti le 14 décembre 2016 ! N'hésitez pas à me soutenir :)

https://itunes.apple.com/us/app/highway-runners/id964932741

331

Raphaël :
Finalement c'est pas si compliqué. smile Et même en C mal codé elle est 4-5 fois plus rapide que celle de l'AMS !
La routine d'AMS peut afficher à n'importe quelle abscisse, pas seulement les multiples de 8 (ça ralentit pas mal, ça)...
Et est-ce qu'il est possible d'utiliser des long à la place des char ?
Oui, si ton sprite est aligné à une adresse paire et que sa largeur est un multiple de 4 (enfin, sinon tu peux gérer ça toi même).
Par contre pour le clipping je ne sais pas du tout commment faire.
Tu testes si le sprite dépasse ou non de l'écran, et tu fais une boucle différente pour les cas qui nécessitent des changements importants par rapport à la boucle principale. Tu peux tout faire dans la même boucle sinon, mais ça complique un peu et surtout, ça ralentit pas mal.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

332

Normalement il n'y aurait aucun problème (une ligne avec caché=1 est carrément sautée, où qu'elle soit)... Parce que tu utilises quelle méthode pour le moment Raphaël?

Chaque ligne à ses paramètres (seulement je n'ai jamais pensé à utiliser x pour positionner le texte : ça c'est le viewer qui le fait. x sert par contre au texte animé).
Sinon c'est pareil j'ai un mode caché. Quand le texte caché est dans l'écran, je passe à la ligne suivante sauf si la touche diamond est pressé.
Par contre je n'utilise pas ta méthode... d'ailleurs je n'ai pas encore bien compris comment tu faisait...enfin si : dans le tableau c'est une ligne supplémentaire mais elle est affiché à la même ordonnée. Je n'avais jamais pensé à faire ça. Pour l'instant je gère tout ligne par ligne et puis c'est tout.
J'ai pas cherché à ma compliqué la vie de ce côté là parce-que c'est déjà assez le foutoir comme ça. grin
D'ailleurs si plusieurs lignes de suites ont les mêmes paramètres (ma syntaxe facilité ça aussi) tous les paramètres des lignes suivante pointent vers les paramètres de la première ligne et du coup je n'alloue pas de mémoire. D'ailleurs c'est souvent que ça arrive et je gagne pas mal de mémoire avec ça parce-que ma structure de paramètres est quand même assez lourde.
La routine d'AMS peut afficher à n'importe quelle abscisse, pas seulement les multiples de 8 (ça ralentit pas mal, ça)...

Tu veux dire quoi par là ? ca change quoi l'abscisse ?
Oui, si ton sprite est aligné à une adresse paire et que sa largeur est un multiple de 4 (enfin, sinon tu peux gérer ça toi même).

Ouais alors je vais déjà essayer de coder une routine clippée ça sera déjà pas mal.
Tu testes si le sprite dépasse ou non de l'écran, et tu fais une boucle différente pour les cas qui nécessitent des changements importants par rapport à la boucle principale. Tu peux tout faire dans la même boucle sinon, mais ça complique un peu et surtout, ça ralentit pas mal.

Par contre pour les sprites clippée il faut afficher bit par bit c'est ça ? Pour ce qui est de la rapidité il y a toujours moyen de se débrouiller même en C.

Et sinon quelqu'un aurait une optimisation à apporter à la routine que j'ai fais ? Parce-que c'est quand même ma première routine graphique, je ne m'y étais jamais intéressé auparavant.

Et au fait pourquoi dans extgraph 2 il n'y a pas de PutBitmap ? Je me trompe pas au moins ? grin Vous avez considéré que celle de l'AMS est assez rapide ?
www.wikio.fr/user1921&info=comments

333

PutBitmap> fonctions SpriteX8*
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

334

Et bon courage pour le clipping.

335

Euh oui précision: les SpriteX8* d'Ext v2 ne sont pas clippées grin
avatar
Que cache le pays des Dieux ? - Forum Ghibli - Forum Littéraire

La fin d'un monde souillé est venue. L'oiseau blanc plane dans le ciel annonçant le début d'une longue ère de purification. Détachons-nous à jamais de notre vie dans ce monde de souffrance. Ô toi l'oiseau blanc, l'être vêtu de bleu, guide nous vers ce monde de pureté. - Sutra originel dork.

336

La routine d'AMS peut afficher à n'importe quelle abscisse, pas seulement les multiples de 8 (ça ralentit pas mal, ça)...

Ah ouais en effet la mienne est foireuse ! sad
Euh oui précision: les SpriteX8* d'Ext v2 ne sont pas clippées

Ouais, en effet. sad Pourtant ça m'aurait bien arrangé. grin
Et bon courage pour le clipping.

Merci. smile Je ne suis plustrop sûr de vouloir continuer, là ! grin Surtout si ça n'est pas plus rapide que celle de l'AMS.
En fait je voulais que la compatibilité avec PedRom soit immédiate mais je vais peut-être quand même utilisé celle de la ROM si je n'y arrive pas.
Et au fait c'est quoi qu'il faut faire pour afficher avec des abscisse différente des multiple de 8. Il faut faire un & binaire... c'est pas ce qui va accélérer la routines en effet. sad
www.wikio.fr/user1921&info=comments

337

Je peux t'envoyer la pre-version 0.81 (Je suis assez lent a coder ces derniers jours).

338

Ouais, d'accord. Comme ça je pourrais tester quand je pense que j'aurais à peu près fini parce-qu'il faut que je soit sûr qu'il n'y est plus de bug avec l'AMS. Et puis je verrai quelles routines de la Rom je vais utiliser pour PedRom afin de faire la version la plus légère possible.
Par contre il y a un truc bizarre lorsque j'allume ma 89 et que ça fait plus d'une heure que je ne l'ai aps allumé, avec la rom 2.09 : ça fait comme avec PedRom il y a un écran noir qui dure 1/2 seconde. Comme je n'ai pas remis la 2.05, je en sais pas si c'est normal ou pas.
www.wikio.fr/user1921&info=comments

339

hwti m'en avait parle. C'est normal. Le constraste est remis a jour apres l'ecran.

340

Ah d'accord.
void PutBitmap(short x, short y,unsigned char *pic,unsigned char *video_plane)
{
	
  short i=0,j=0;
  short nb_l=pic[1];
  short nb_c=pic[3];
  pic=pic+4;
  while(j<nb_l)
  {
       short y_offset = (y<<8)-(y<<4);
       short x_pic = x;
       short i=0;
       while(i<nb_c)
       {
  	     short offset = ((y_offset + x_pic) >> 3);
  	     *(video_plane+(offset)) |=(*pic++)>>(x_pic&7);
  	     x_pic=x_pic+8;
         i=i+8;
       }
       y++;
       j++;
  }
  

}


Ma routine ne marche toujours pas. J'ai rajouté >>(x_pic&7) et ça affiche bien à partir du bon pixel mais quand ce n'est pas un multiple de 8 l'image en prend un coup. C'est un peu le même bug que celle de l'AMS en mode A_REVERSE.
Il faut que je change quoi ?
www.wikio.fr/user1921&info=comments

341

Tu devrais mettre des boucles for, ça serait plus lisible smile
Et pourquoi tu n'utilises pas += ?

Sinon, en ce qui concerne la routine elle-même :
[li]La façon dont tu récupères la largeur et la hauteur du bitmap n'est pas bonne, là, tu fais : nb_l = (short)*(unsignd char *)(pic+1); Il faudrait que tu récupères tout : nb_l = *(unsigned short *)(pic+0);[/li]
[li]*video_plane est de type char, donc c'est normal que tu ne puisses pas lui affecter quelque chose qui prend plus de 8 bits.
Je te propose de procéder en 2 fois : tu écris d'abord la partie la plus à gauche de ton groupe de 8 pixels, puis la partie la plus à droite.[/li]

En ce qui concerne l'optimisation maintenant :
[li]Calcule l'offset sur y en dehors de la boucle (les instructions de shift ne sont pas super rapides sur le 68k)[/li]
[li]Calcule ton offset en octets directement, ça t'évitera le >>3[/li]
[li]Ajoute l'offset à video_plane en dehors des boucles (au tout début)[/li]
[li]C'est possible que GCC optimise tout ça, mais il vaut mieux le faire par toi-même[/li]
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

342

Je te propose de procéder en 2 fois : tu écris d'abord la partie la plus à gauche de ton groupe de 8 pixels, puis la partie la plus à droite.

et il faut faire comment ?
Sinon je suis arrivée à optimiser correctement la routine, merci pour tes conseils Sasume. smile
www.wikio.fr/user1921&info=comments

343

Tu as une partie qui fait 8 pixels (contenue dans un octet), et tu dois l'afficher en la décalant sur le côté :
Mémoire de destination :
[ | | | | | | | ][ | | | | | | | ]

Partie de l'image (8 pixels) décalée (x&7 = 5) :
          [7|6|5|4|3|2|1|0]

Afficher d'abord (dans le premier octet de destination) :
[ | | | | |7|6|5]

Puis (dans le deuxième octet de destination) :
                 [4|3|2|1|0| | | ]

Afin de donner comme résultat :
[ | | | | |7|6|5][4|3|2|1|0| | | ]

(chaque case représente un bit, un octet est entouré de [ ])
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

344

Ok, super ! Je vais vite comprendre avec ce schéma. Merci bien je pense que je vais y arriver cette fois.
www.wikio.fr/user1921&info=comments

345

Bonne chance smile
(au fait, j'ai édité quelques détails)
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

346

bon je n'ai pas tout corriger mais ça serait bon un truc comme ça ? :
void PutBitmap(short x, short y,unsigned char *pic,unsigned char *video_plane)
{
	
  short i=0,j=0;
  short nb_l=pic[1];
  short nb_c=pic[3];
  pic=pic+4;
  for(j=0;j<nb_l;j++)
  {
       
       short x_ = x;
       short i=0;
       unsigned char *pointeur = (video_plane+(((y<<8)-(y<<4)+x)>>3));
       /*                                    (256y-16y+x)/8       */
       for(i=0;i<nb_c;i=i+8)
       {
  	     
  	     *(pointeur) |=(*pic)>>(x_&7);
  	     *(pointeur+1) |=(*pic)<<((8-x)&7);
  	     *pic++;
  	     *pointeur++;
  	    
  	     x_=x_+8;
      
       }
       y++;
  }
  

}


*(pointeur+1) |=(*pic)<<((8-x)&7);
J'ai trouvé ça en regardant les sources de OrageGL grin
Sauf qu'il y a un moment où il y a deux images décalées sinon 7/8 sur marche il me semble. Mais je ne sais pas si c'est ça que tu veux me faire comprendre avec ton schéma... je vais essayer de comprendre cette fois. grin
www.wikio.fr/user1921&info=comments

347

Ah oui, OrageGL utilise cette technique pour afficher les sprites 8x8.
La formule (8-x)&7 n'est pas correcte : si x=0 par exemple, tu devrais théoriquement obtenir 8. Mais là tu auras 0.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

348

Ok je vais faire autrement alors. grin Là c'est clair que la rapidité à déjà été divisé par deux alors avec la clipping ça risque d'être même plus lent que l'AMS. sad

voilà je ne vois pas comment faire mieux :
void PutBitmap(short x, short y,unsigned char *pic,unsigned char *video_plane)
{
	
  short i=0,j=0;
  short nb_l=pic[1];
  short nb_c=pic[3];
  pic=pic+4;
  for(j=0;j<nb_l;j++)
  {
       
       short x_ = x;
       short i=0;
       unsigned char *pointeur = (video_plane+(((y<<8)-(y<<4)+x)>>3));
       /*                                    (256y-16y+x)/8       */
       for(i=0;i<nb_c;i=i+8)
       {
  	     
  	     short mask = x_&7;
  	     *(pointeur) |=(*pic)>>(mask);
  	     if(mask)
  	     *(pointeur+1) |=(*pic)<<(8-mask);
  	     *pic++;
  	     *pointeur++;
  	    
  	     x_=x_+8;
      
       }
       y++;
  }
  

}
www.wikio.fr/user1921&info=comments

349

C'est possible que TIGCC l'optimise de lui même, mais tu peux incrémenter ton pointeur avant d'utiliser *(pointeur+1)=, ça te permettra d'écrire *(pointeur)=.
Là aussi, ça me paraît tout à fait possible que TIGCC l'optimise de lui-même, mais tu peux sortir le pointeur=(video_plane+offset) de la prmière boucle : il n'y a que y qui augmente de 1 entre chaque itération de la boucle, dans ton code, cela revient à rajouter 30 à pointeur.

Et au passage, tu récupères toujours aussi mal la taille de l'image (nb_l et nb_c).
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

350

Au fait, TI-GCC te met un warning ou pas pour "*pic++;" et "*pointeur++;" ?

Parce que l'étoile est totalement inutile... (cela dit, je pense que même CC génère le même code que sans étoile smile)

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

351

Et aussi, si tu veux optimiser les choses :
- tu peux calculer le nb d'itérations de la boucle moins 1 avec "int n=(nb_c-1)>>3;" puis "do { ...boucle... } while (n--);"
- tu peux mettre ton "if (mask)" en dehors de la boucle, ou bien le supprimer totalement (sinon, ça ralentit pas mal : +8 cycles si mask!=0)

Enfin, je te conseillerais _très vivement_ d'indenter la ligne après "if (mask)", sinon tu finiras par te planter...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

352

void PutBitmap(short x, short y,unsigned char *pic,unsigned char *video_plane)
{
	
  short i=0,j=0;
  short nb_l=*(unsigned short *)(pic+0);
  short nb_c=*(unsigned short *)(pic+2);
  pic=pic+4;
  for(j=0;j<nb_l;j++)
  {
       
       short x_ = x;
       short i=0;
       unsigned char *pointeur = (video_plane+(((y<<8)-(y<<4)+x)>>3));
       /*                                    (256y-16y+x)/8       */
       for(i=0;i<nb_c;i=i+8)
       {
  	     
  	     short mask = x_&7;
  	     if(mask)
  	     *(pointeur+1) |=*(pic)<<(8-mask);
  	     *(pointeur++) |=(*pic++)>>(mask);
  	     x_=x_+8;
      
       }
       y++;
  }
  

}

Je pense que là ça va déjà mieux. smile ... parce-qu'en même temps que je teste la routine je fait un bench et là j'en suis à 550-560 contre 209 pour l'AMS... il faudra que je vois après clipping aussi. Mais c'est bien possible de faire deux fois plus vite que l'AMS en C, non ?
www.wikio.fr/user1921&info=comments

353

Pkoi t'as échangé les deux affectations? Et tu n'as pas lu ./351, apparemment...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

354

- tu peux calculer le nb d'itérations de la boucle moins 1 avec "int n=(nb_c-1)>>3;" puis "do { ...boucle... } while (n--);"

ca va beaucoup t'étonner mais c'est moins rapide : l'image fait 49 de longeur : elle n'est peut-être pas assez longue pour que ça soit rentable ? Ou alors GCC l'optimise mal... je sais pas.
- tu peux mettre ton "if (mask)" en dehors de la boucle, ou bien le supprimer totalement (sinon, ça ralentit pas mal : +8 cycles si mask!=0)

J'ai pas bien compris là : comment en dehors de la boucle ? au pire je le supprime et j'exécute tout le temps la seconde ligne c'est ça ?

EDIT : C'est marrant mais le if (mask) ne sert plus à rie maintenant... je comprend pas pourquoi. Mais enfin tant mieux.
www.wikio.fr/user1921&info=comments

355

ca va beaucoup t'étonner mais c'est moins rapide : l'image fait 49 de longeur : elle n'est peut-être pas assez longue pour que ça soit rentable ? Ou alors GCC l'optimise mal... je sais pas.

hum
C'est vraiment bizarre, effectivement. Et 49 de longueur, c'est très largement suffisant, a priori (7 itérations). En plus, c'est vraiment tout pré-mâché, le compilo n'a rien à faire pour prendre la meilleure solution, donc je ne vois pas pkoi ça foirerait...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

356

Bon, je viens de regarder ce que pond TIGCC : il utilise certains registres inutilement, ce qui fait qu'il utilise d0-d7 et qu'il y a des chances qu'il se vautre dans l'allocation de registres... Si tu pouvais poster le code qui est plus lent, je veux bien voir ce que ça donne...

« The biggest civil liberty of all is not to be killed by a terrorist. » (Geoff Hoon, ministre des transports anglais)

357

Hmmm... Encore un problème à déboguer pour moi? sad
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

358

Non non j'ai rien dit ! C'est de ma faute en fait parce-que je calculais le nombre d'itération dans la première boucle alors que ça peut se calculer très facilement au début de la fonction :

void PutBitmap(short x, short y,unsigned char *pic,unsigned char *video_plane)
{
	
  short i=0,j=0;
  short nb_c=*(unsigned short *)(pic+0);
  short nb_l=*(unsigned short *)(pic+2);
  pic=pic+4;
  short height = (nb_l/8)+1;
  for(j=0;j<nb_c;j++)
  {
       
       short x_ = x;
       short i=0;
      
       unsigned char *pointeur = (video_plane+(((y<<8)-(y<<4)+x)>>3));
       /*                                    (256y-16y+x)/8       */
         
       short n=height;
       while(n--)
       {
  	     
  	     short mask = x_&7;
  	     *(pointeur+1) |=*(pic)<<(8-mask);
  	     *(pointeur++) |=*(pic++)>>(mask);
  	     x_=x_+8;
  	     
      
       }
       y++;
  }
  

}

D'ailleurs j'emploie cette optimisation un peu patout dans mon programme mais je ne vois jamais les optimisation tout de suite : j'essaye d'avoir d'avoir quelque chose de fonctionnel et de facile à comprendre.

et par contre pourquoi quand je fais ça :

*(pointeur+1) |=*(pic)<<(8-x_&7);
*(pointeur++) |=*(pic++)>>(x_&7);

ça foire et qaund je fais ça :
short mask = x_&7;
*(pointeur+1) |=*(pic)<<(8-mask);
*(pointeur++) |=*(pic++)>>(mask);
ça marche ?

www.wikio.fr/user1921&info=comments

359

Raphaël
: Non non j'ai rien dit ! C'est de ma faute en fait

OK. smile
et par contre pourquoi quand je fais ça :

*(pointeur+1) |=*(pic)<<(8-x_&7);
*(pointeur++) |=*(pic++)>>(x_&7);

ça foire et qaund je fais ça :
short mask = x_&7;
*(pointeur+1) |=*(pic)<<(8-mask);
*(pointeur++) |=*(pic++)>>(mask); ça marche ?

Il manque des parenthèses autour de x_&7. Mais la deuxième solution est meilleure de toute façon. (Cela dit, elles reviennent au même, parce qu'il y a une optimisation pour ça dans GCC.)

Et j'ai mieux:
*(pointeur++) |=*(pic)>>(mask);
*(pointeur) |=*(pic++)<<(8-mask);
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

360

Ah ouais en effet !
Et donc pour le clipping en x, pour les sprites qui doivent être clippés il faut afficher bit par bit ?
www.wikio.fr/user1921&info=comments