30

Comme je l'ai dit "elle n'a pas du tout la prétention d'être state-of-the-art ou quoi que ce soit", et encore moins la prétention d'être nouvelle ^^

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

31

En fait, c'est ceci :
Pollux
: je viens de trouver une méthode

Qui m'a laissé penser ça wink
ça aurait été sympathique cependant si tu avais vraiment trouvé une nouvelle méthode oui
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. »

32

>Comme je l'ai dit "elle n'a pas du tout la prétention d'être state-of-the-art ou quoi que ce soit", et encore moins la prétention d'être nouvelle
Je m'en doute.

J'ai trouvé des vieux mails dans les newgroup qui en parlaient dans les années 90-95 (je ne saurai pas les retrouver d'ailleurs!)
Pas trouvé plus vieux pour le moment.

33

Sasume :
ça aurait été sympathique cependant si tu avais vraiment trouvé une nouvelle méthode oui

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 triroll
De toute façon, si on veut vraiment gagner du temps sur le scrolling, ce n'est pas en cherchant à optimiser ce style de routine bas niveau (shift d'un écran virtuel vers un autre) qu'on va y arriver, mais plutôt en se plaçant à un plus haut niveau ^^ (notamment avec des précalculs pour éviter le scrolling, de façon bête et méchante à la compilation ou au lancement, ou de façon "just in time" si le nb de tiles différents à afficher simultanément est faible)
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. Si mes souvenirs sont bons Genlib ne fait pas ça, donc même si la routine de scrolling était optimale ça fait forcément perdre un temps fou... Surtout que les routines de tiles et les routines de scrolling se combinent bien entre elles, donc c'est pas très compliqué à réaliser smile
(et d'ailleurs même si on ne fait pas d'animations, c'est pas très désirable que ça saccade quand il faut redessiner l'écran virtuel : mieux vaut une routine d'affichage toujours moyennement rapide qu'une routine d'affichage souvent rapide mais parfois lente...)

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

34

Pollux :
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 triroll
Qui sait ? Tu aurais pu révolutionner quelque chose wink (si si on peu parler de révolution sur TI trigic)
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.
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. »

35

Ben comme je le dis à la fin de mon post, c'est souvent le pire des cas qui est le plus important... Alors après c'est vrai que si on update 1 frame sur 5, ce serait encore mieux de mettre à jour 1/5è de l'écran virtuel à chaque fois smile Mais je ne sais pas s'il y a des libs capables de faire ça ^^

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

36

Je n'en connais aps non plus (on ok ma connaissance des libs graphiques TI est restreinte, mais bon grin))
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

37

./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 smile

>donc ça peut rester intéressant de précalculer l'ensemble de la zone à scroller.
Pas lorsque tu approches des 1000 tiles pour ta map smile

>mais plutôt une frame sur 5 voire 10
Ca varie entre 4 et 16 dans SMA.

38

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 smile

Bah SMA n'est pas non plus un modèle de fluidité (15 fps), donc je veux bien croire qu'un rafraîchissement d'écran virtuel passe inaperçu quand on doit par ailleurs faire N affichages de plans transparents à chaque frame smile Pour des jeux plus simples graphiquement mais plus exigeants en terme de framerate, ça n'est pas imperceptible d'avoir soudainement un frame qui prend 90000 cycles en plus ^^

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

39

Meme a 30 fps, ca reste imperceptible. Sinon ca veut dire que le jeu a été mal "calibré".

PS: SMA fonctionne à 15 ou 30 FPS. Perso je le fais fonctionner à 30 avec 1 plan (trop juste pour 2 plans sur HW1). Mais sur HW2, ca tourne sans problème à 30.

PPS: Et faire plus que 30 fps pour la partie graphique ne sert a rien sur TI. Pour la partie physique/interface, rien n'empeche qu'elle fonctionne a un fréquence plus elevée (c'est encore le cas pour SMA).

40

Salut. J'ai quelques questions sur le code qu'a poste Pollux :

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 ...
}


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
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.

J'ai surement loope un truc , c'est pour cela que je comprends tout de travers.

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.

41

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 1octet
En fait, on ne peut pas (normalement) faire : void *var;var++;...
Car « void » n'a pas de taille. Sur TIGCC, tu peux le faire (dans le sens où ça fonctionne, mais ce n'est pas « bien ») et le pas est bien d’un octet.
avatar

42

C'est une extension GCC, mais c'est parfaitement bien défini : void a une taille, et cette taille c'est 1 smile (comme un char)
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 );

1. exactement
2. exactement
3. exactement, sauf qu'en fait là les mots font 32 bits (cf plus bas), donc il faut remplacer 16 par 32
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.

En fait non, ça n'a rien d'étrange puisque src_odd et src_even sont des pointeurs vers des longs, alors que dst_ptr est un pointeur vers un short. Du coup un décalage de 32 bits = 1 "++" pour src _odd = 1 "++" pour src_even = 2 "++" pour dst_ptr happy
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.

Exactement ^^

Si tu fais un schéma :
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

Bref, on va écrire à dst_ptr 0xdefg, puis 0xhijk, etc... Vérifie qu'à l'étape suivante tu obtiens bien 0xlmno et 0xpqrs, et ça devrait te convaincre qu'en sortie on a bien le bitmap d'origine décalé de "shift" pixels smile

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

43

Merci Pollux. C'est vraiement mes debuts en manipulation de bits et je pense que j'ai appris l'essentiel dans ce topic.
Me reste plus qu'a jeter un oeil aux autres operateurs de bits pour voler de mes propres ailes.

44

Au fait, je pige pas bien, je croyais que le decalage droite virait les biits les plus a droite de la representation binaire.

45

Ben oui, 0xabcdefgh >> 4 = 0xabcdefg, mais si après tu castes le résultat en short, seuls les 16 bits de poids faible seront conservés, donc ça donne 0xdefg ^^

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

46

voila ce qui m'avait echapper. Et comme en plus j'avais pas fait attention dans ton poste precedent
- a la disparition du h
-au short casting
C'est limpide maintenant oui

47

Voila ce que j'ai pu faire avec le coprs de ta routine Pollux.

 
#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 );



Maintenant mon soucis c'est de gerer le fait que *dst_ptr et *src sont en fait des adresses situees dans le meme ecran.
Ces adresses dependent toutes 2 de screenptr = LCD_MEM. Il n'y a pas d'interet a utiliser un ecran virtuel puisque je veux etre le plus rapide possible.

Je vais donc devoir adapter la routine selon que je scrolle horizontalement ou verticalement.