Pollux
: je viens de trouver une méthode
Sasume :
ça aurait été sympathique cependant si tu avais vraiment trouvé une nouvelle méthode![]()
Pollux :Qui sait ? Tu aurais pu révolutionner quelque chose
Bah de toute façon c'est un problème à la fois extrêmement simple (on est bien loin d'un mode 7 par exemple) et qui a dû être étudié par bcp de monde, donc ça aurait été étonnant qu'en y réfléchissant 5 minutes j'ai trouvé une solution meilleure que toutes les autres
Dans le même ordre d'idée, ça ne sert à rien de gagner 20% de vitesse sur une routine de scrolling si on fait par ailleurs une copie inutile d'un écran entier... Du coup si par exemple l'écran de tiles à scroller est redessiné à chaque fois (pour gérer des animations par exemple), c'est extrêmement important que la routine de scrolling soit intégrée à la routine de dessin de tiles et que les tiles ne soient dessinés nulle part en mémoire.En général quand les tiles sont animés, ils ne sont pas mis à jour à chaque frame, mais plutôt une frame sur 5 voire 10 (sinon l'animation est trop rapide), donc ça peut rester intéressant de précalculer l'ensemble de la zone à scroller.
PpHd :
./33: Le rafraichissement de l'ecran virtuel est imperceptible en temps normal (sauf le faire tout le temps).
SMA en fait parfois toutes les 4 frames sans repercussion sur le frame rate.
Parfois meme tout le temps dans certains niveaux
void *src = ... à calculer ..., *dst = écran_virtuel; int shift = ... à calculer ...; unsigned long *src_even = src, *src_odd = src+2; unsigned short *dst_ptr = dst; while (nb_lines--) { ... calculer le nombre de mots à afficher ... // La boucle interne : do { *dst_ptr++ = *src_even++ >> shift; *dst_ptr++ = *src_odd++ >> shift; } while (n--); ... ajuster les pointeurs pour la ligne suivante ... }
andoh_wilfried :En fait, on ne peut pas (normalement) faire : void *var;var++;...
1- j'ai rien trouve sur l'arithemetique des (void *), j'ai donc suppose que cela fonction comme un (char *) : le pas est de 1octet
andoh_wilfried :
1- j'ai rien trouve sur l'arithemetique des (void *), j'ai donc suppose que cela fonction comme un (char *) : le pas est de 1octe
2- src_even et scr_odd sont distants de 2 octets
3- un mot(word) machine fait 16 bits = 2 octets = sizeof(unsigned short) sur la TI, je ne comprends pas ceci :
le nombre de mot en les points (x0,y0) et (x1,y1) est : l = x1 - x0 + 1 ; n l / 16 + ( l % 16 != 0 );
la boucle interne do { ... } while() fait n iteration en avancant d'un mot a chaque iteration alors que dst_ptr est depalce de 2 mot. Cela me semble etrange.
D'ailleur l'astuce du decalage a droite m'echappent completement.
Tout ce que je vois c'est que vire de chaque long les shift bits de droite.
je suppose que shift represente le nombre de bits a copier dans le 1er mot.
bitmap source = (en hexa) ab cd ef gh ij kl mn ... ^ ^ | | | src_odd | src_even Si shift = 4 bits (1 chiffre hexa) : *src_even == 0xabcdefgh (short)(*src_even>>4) == 0x defg *src_odd == 0xefghijkl (short)(*src_odd>>4) == 0x hijk
#define BYTE_PER_SCREEN_ROW 30 #define BYTE_PER_SHORT 16 #define BYTE_PER_LONG 32 // Adresse paire obligatoirement char *src = screenptr + y0 * BYTE_PER_SCREEN_ROW + 2 * ( x0 / BYTE_PER_SHORT ); // Nombre de bits a copier dans le 1er mots unsigned short shift = BYTE_PER_LONG - x0 % BYTE_PER_LONG; if( shift == BYTE_PER_LONG ) shift = 0; // Adresse paire obligatoirement unsigned short *dst_ptr = screenptr + y1 * BYTE_PER_SCREEN_ROWBYTE_PER_SCREEN_ROW + 2 * ( x1 / BYTE_PER_SHORT ); unsigned short l = x1 - x0 + 1; unsigned short nb_mots = l / BYTE_PER_LONG + ( l % BYTE_PER_LONG != 0 ); unsigned short nb_lines = y1 - y0 + 1; unsigned long *src_even, *src_odd; do { n = nb_mots; src_even = src; src_even = src + 2; do { *dst_ptr++ = *src_even++ >> shift; *dst_ptr++ = *src_odd++ >> shift; } while( --n ); src += BYTE_PER_SCREEN_ROW; } while( --nb_lines );