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 ?
while(n--) { short mask jbra .L21 .even .L24: #L1449 = x_&7; move.w %d3,%d1 and.w #7,%d1 #L1456 *(pointeur++) |=*(pic)>>(mask); clr.w %d0 move.b (%a1),%d0 asr.w %d1,%d0 or.b (%a0),%d0 move.b %d0,(%a0)+ #L1472 *(pointeur) |=*(pic++)<<(8-mask); //*(pointeur+1) |=*(pic)<<(8-mask); //*(pointeur++) |=*(pic++)>>(mask); //*(pointeur++) |=((x_>0)?(*(pic)>>(mask)):0); //*(pointeur) |=((x_<152)?(*(pic++)<<(8-mask)):0); clr.w %d0 move.b (%a1)+,%d0 moveq.l #8,%d6 sub.w %d1,%d6 lsl.w %d6,%d0 or.b %d0,(%a0) #L1498 x_=x_+8; } addq.w #8,%d3 .L21: dbra %d2,.L24 #L1508 y ... add.w #256,%d4 add.w #16,%d5 #L1366 ; ... addq.w #1,%d7 .L17: cmp.w %a2,%d7 jblt .L25 #L1514 } //*((char*)LCD_MEM+addr)=x&7; void _main(void) { movm.l (%sp)+,#0x3cf8 unlk %a6 rts
while(n--) { short mask jbra .L21 .even .L24: #L1449 = x_&7; //*(pointeur++) |=*(pic)>>(mask); //*(pointeur) |=*(pic++)<<(8-mask); move.w %d4,%d2 and.w #7,%d2 #L1460 *(pointeur+1) |=*(pic)<<(8-mask); clr.w %d0 move.b (%a1),%d0 moveq.l #8,%d1 sub.w %d2,%d1 lsl.w %d1,%d0 or.b %d0,1(%a0) #L1479 *(pointeur++) |=*(pic++)>>(mask); //*(pointeur++) |=((x_>0)?(*(pic)>>(mask)):0); //*(pointeur) |=((x_<152)?(*(pic++)<<(8-mask)):0); clr.w %d0 move.b (%a1)+,%d0 asr.w %d2,%d0 or.b (%a0),%d0 move.b %d0,(%a0)+ #L1500 x_=x_+8; } addq.w #8,%d4 .L21: dbra %d3,.L24 #L1510 y ... add.w #256,%d5 add.w #16,%d6 #L1366 ; ... addq.w #1,%a2 .L17: move.w %a3,%d0 cmp.w %a2,%d0 jbgt .L25 #L1516 } //*((char*)LCD_MEM+addr)=x&7; void _main(void) { movm.l (%sp)+,#0x3cf8 unlk %a6 rts
while(n--) { short mask = x_&7; *(pointeur+1) |=((x_<232)?(*(pic)<<(8-mask)):0); *(pointeur) |=((x_>-1)?(*(pic)>>(mask)):0); *pic++; *pointeur++; x_=x_+8;
Kevin Kofler :
Hmmm... Encore un problème à déboguer pour moi?
while(n--) { short mask = x_&7; if(x_<232) { *(pointeur+1) |=(((*(pic)<<(8-mask)))); } if(x_>-1) { *(pointeur) |=((*(pic)>>(mask))); } pointeur++; pic++; x_=x_+8; }
- sortir "mask" de la boucle (il ne va pas bouger)
- transformer >-1 en >=0 (peut-être que GCC l'optimise, je sais pas)
- inverser l'ordre des deux modifications de la mémoire
- mettre le "pointeur++" entre les deux et transformer les "pointeur+1" en "pointeur" tout court (parce qu'on aura fait le ++ entre-temps).
Raphaël :
ok, merci bien je vais essayer tout ça.
Par contre je en comprends pas ton premier truc :- sortir "mask" de la boucle (il ne va pas bouger)
Alors sinon :- transformer >-1 en >=0 (peut-être que GCC l'optimise, je sais pas)
Ca a marché avec une réduction de 3 octets en plus.
Déplacer "int mask=x_&7" pour le mettre avant la boucle...
Moi je parierais plutôt pour 2 (voire 4)... Je vois pas comment tu peux avoir une réduction impaire.
Cela dit, 2x plus rapide qu'AMS c pas la gloire non plus Tu peux largement améliorer le clipping en déterminant avant la boucle quelle zone sera à afficher.
Tu peux largement améliorer le clipping en déterminant avant la boucle quelle zone sera à afficher.
Raphaël :
Voici avec ton optimisation :while(n--) { short mask jbra .L21 .even .L24: #L1449 = x_&7; move.w %d3,%d1 and.w #7,%d1 #L1456 *(pointeur++) |=*(pic)>>(mask); clr.w %d0 move.b (%a1),%d0 asr.w %d1,%d0 or.b (%a0),%d0 move.b %d0,(%a0)+ #L1472 *(pointeur) |=*(pic++)<<(8-mask); //*(pointeur+1) |=*(pic)<<(8-mask); //*(pointeur++) |=*(pic++)>>(mask); //*(pointeur++) |=((x_>0)?(*(pic)>>(mask)):0); //*(pointeur) |=((x_<152)?(*(pic++)<<(8-mask)):0); clr.w %d0 move.b (%a1)+,%d0 moveq.l #8,%d6 sub.w %d1,%d6 lsl.w %d6,%d0 or.b %d0,(%a0) #L1498 x_=x_+8; } addq.w #8,%d3 .L21: dbra %d2,.L24 #L1508 y ... add.w #256,%d4 add.w #16,%d5 #L1366 ; ... addq.w #1,%d7 .L17: cmp.w %a2,%d7 jblt .L25 #L1514 } //*((char*)LCD_MEM+addr)=x&7; void _main(void) { movm.l (%sp)+,#0x3cf8 unlk %a6 rts
et voici sans :while(n--) { short mask jbra .L21 .even .L24: #L1449 = x_&7; //*(pointeur++) |=*(pic)>>(mask); //*(pointeur) |=*(pic++)<<(8-mask); move.w %d4,%d2 and.w #7,%d2 #L1460 *(pointeur+1) |=*(pic)<<(8-mask); clr.w %d0 move.b (%a1),%d0 moveq.l #8,%d1 sub.w %d2,%d1 lsl.w %d1,%d0 or.b %d0,1(%a0) #L1479 *(pointeur++) |=*(pic++)>>(mask); //*(pointeur++) |=((x_>0)?(*(pic)>>(mask)):0); //*(pointeur) |=((x_<152)?(*(pic++)<<(8-mask)):0); clr.w %d0 move.b (%a1)+,%d0 asr.w %d2,%d0 or.b (%a0),%d0 move.b %d0,(%a0)+ #L1500 x_=x_+8; } addq.w #8,%d4 .L21: dbra %d3,.L24 #L1510 y ... add.w #256,%d5 add.w #16,%d6 #L1366 ; ... addq.w #1,%a2 .L17: move.w %a3,%d0 cmp.w %a2,%d0 jbgt .L25 #L1516 } //*((char*)LCD_MEM+addr)=x&7; void _main(void) { movm.l (%sp)+,#0x3cf8 unlk %a6 rts
C'est idiot. Tu n'as besoin de clipper que selon la taille d'un écran de TI-92+. Même si a fonction tourne sur une 89...
#define height_screen 100 #define width_screen 160 __attribute__((regparm))void PutBitmap(short x, short y,BITMAP* BMP,unsigned char *video_plane) { short i=0,j=0; short nb_c=BMP->NumCols; short nb_l=BMP->NumRows; unsigned char *pic=BMP->Data; if(y+nb_l>=height_screen) nb_l=height_screen-y; short lenght = (nb_c>>3)+1; short nb_sprite; if(y<0) { nb_sprite = -y*lenght; pic=pic+nb_sprite; nb_l=nb_l+y; y=0; } short nb_sprite_out_right =0; if((x+nb_c)>=width_screen-8) { nb_sprite_out_right = ((x+nb_c-(width_screen-2))>>3); lenght = lenght-nb_sprite_out_right; } short nb_sprite_out_left=0; if(x<0) { nb_sprite_out_left=((-1-x)>>3); lenght = lenght - nb_sprite_out_left; } if(lenght<0) lenght=0; short mask1 = x&7; short m=nb_l; for(j=0;j<nb_l;j++) { short x_ = x; short i=0; if(x_<0) x_=-1; unsigned char *pointeur = (video_plane+(((y<<8)-(y<<4)+x_)>>3)); /* (256y-16y+x)/8 */ short n=lenght; pic=(pic+nb_sprite_out_left); while(n--) { if(x_>=0) *(pointeur) |=((*(pic)>>(mask1))); pointeur++; if(x_<width_screen-8) { *(pointeur) |=(((*(pic)<<(8-mask1)))); } pic++; x_=x_+8; } y++; pic=pic+nb_sprite_out_right; }
__attribute__((regparm))void PutBitmap(short x, short y,BITMAP* BMP,unsigned char *video_plane) { short i=0,j=0; short nb_c=BMP->NumCols; // on récupère le nombre de lignes du bitmap short nb_l=BMP->NumRows; // on récupère le nombre de colonnes du bitmap unsigned char *pic=BMP->Data; // on récupère un pointeur vers le Bitmap lui même if(y+nb_l>=height_screen) // si y + nombre de ligne > bas de l'écran nb_l=height_screen-y; // nombre de ligne = bas de l'écran - y. short lenght = (nb_c>>3); // on calcule la longeur d'une ligne en octets : nombre de colonnes / 8 if((lenght*8)!=nb_c) // si la divison comporte un reste on ajout 1 lenght++; short nb_sprite_out_up; if(y<0) // si le début du sprite est en dehors de l'écran en haut { nb_sprite_out_up = -y*lenght; // on calcule le nombre de sprite en dehors de l'écran : - le nb de ligne en dehors de l'écran * la longeur d'une ligne en octet pic=pic+nb_sprite_out_up; nb_l=nb_l+y; y=0; } short nb_sprite_out_right =0; if((x+nb_c)>width_screen+(x&7)-8) { nb_sprite_out_right = ((x+nb_c-(width_screen+(x&7)))>>3)+1; lenght = lenght-nb_sprite_out_right; } short nb_sprite_out_left=0; if(x<0) { nb_sprite_out_left=((-1-x)>>3); lenght = lenght - nb_sprite_out_left; } if(lenght<0) lenght=0; short mask1 = x&7; short m=nb_l; if(x<0) x=-1; 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 */ short n=lenght; pic=(pic+nb_sprite_out_left); while(n--) { if(x_>=0) *(pointeur) |=((*(pic)>>(mask1))); pointeur++; if(x_<width_screen-8) { *(pointeur) |=(((*(pic)<<(8-mask1)))); } pic++; x_=x_+8; } y++; pic=pic+nb_sprite_out_right; } }
if((x+nb_c)>width_screen+(x&7)-8) { nb_sprite_out_right = ((x+nb_c-(width_screen+(x&7)))>>3)+1; lenght = lenght-nb_sprite_out_right; }
Raphaël :
Je sais pas si Sasume, par exemple, tu as clippés les sprites d'extgraph 2 comme ça, mais je ne pensais pas du tout au mask pour le test du clipping. Et j'ai essayé ça par hasard parce-que je en sais même pas qu'elle valeur il contient ni même à quoi il sert exactement !
si ça se peut il faut faire pareil à gauche, non ?Ben c'est à toi de voir si tu penses que c'est indispensable ou non... Réfléchis, fais des shémas et tu verras si c'est indispensable. Je trouve ça moyen de programmer au hasard. En tout cas, je doute que j'utiliserai tes programmes si toi-même tu n'es pas sûr de ce que tu fais.
__attribute__((regparm))void PutBitmap(short x, short y,BITMAP* BMP,unsigned char *video_plane) { short j=0; short nb_c=BMP->NumCols; // on récupère le nombre de lignes du bitmap short nb_l=BMP->NumRows; // on récupère le nombre de colonnes du bitmap unsigned char *pic=BMP->Data; // on récupère un pointeur vers le Bitmap lui même if(y+nb_l>=height_screen) // si y + nombre de ligne > bas de l'écran nb_l=height_screen-y; // nombre de ligne = bas de l'écran - y. short lenght = ((nb_c+7)>>3); // on calcule la longeur d'une ligne en octets : nombre de colonnes / 8 short nb_sprite_out_up; if(y<0) // si le début du sprite est en dehors de l'écran en haut { nb_sprite_out_up = -y*lenght; // on calcule le nombre de sprite en dehors de l'écran : - le nb de ligne en dehors de l'écran * la longeur d'une ligne en octet pic=pic+nb_sprite_out_up; nb_l=nb_l+y; y=0; } short nb_sprite_out_right =0; if((x+(lenght<<3))>=width_screen) { nb_sprite_out_right = ((x+(lenght<<3)-(width_screen))>>3); lenght = lenght-nb_sprite_out_right; } short nb_sprite_out_left=0; if(x<0) { nb_sprite_out_left=((-1-x)>>3); lenght = lenght - nb_sprite_out_left; } if(lenght<0) lenght=0; short mask1 = x&7; if(x<0) x=-1; for(j=0;j<nb_l;j++) { short x_ = x; unsigned char *pointeur = (video_plane+(((y<<8)-(y<<4)+x_)>>3)); /* (256y-16y+x)/8 */ short n=lenght; pic=(pic+nb_sprite_out_left); while(n--) { if(x_>=0) *(pointeur) |=((*(pic)>>(mask1))); pointeur++; if(x_<=width_screen-8) { *(pointeur) |=(((*(pic)<<(8-mask1)))); } pic++; x_=x_+8; } y++; pic=pic+nb_sprite_out_right; } }
n=n-2; if(x_>=0) *(pointeur) |=((*(pic)>>(mask1))); pointeur++; if(x_<=width_screen-8) *(pointeur) |=(((*(pic)<<(8-mask1)))); pic++; x_=x_+8; while(n--) { *(pointeur++) |=((*(pic)>>(mask1))); *(pointeur) |=(((*(pic++)<<(8-mask1)))); x_=x_+8; } if(x_>=0) *(pointeur) |=((*(pic)>>(mask1))); pointeur++; if(x_<=width_screen-8) *(pointeur) |=(((*(pic)<<(8-mask1)))); pic++; x_=x_+8;