bon, bah comme c'est demandé, et que ça pourrait toujours servir ....
Scrolling en C sur 68k
Comment faire pour scroller l'écran en C ?
Aujourd'hui, nous allons voir comment faire "scroller" l'écran dans les 4 directions : haut, bas, gauche, droite (amusez-vous à faire des combos, haut-gauche, bas-droite si vous voulez une fois que vous aurez compris le truc

)
Codage en mémoireVoyons déjà comment sont codés les "zolis pixels" que vous voyez à l'écran :
Sur les 68k, l'adresse de l'écran est 0x4c00, le 0x signifiant bien sûr que c'est en héxadécimal... Chaque octet représente 8 pixels, avec un 1 si le pixel est allumé, ou un 0 s'il est éteint. Pour accéder à un pixel bien particulier de l'écran (exemple : le 42ème de la 37ème ligne), il va falloir faire des manipulations avec des masques et des décalages, mais ce n'est pas (tout à fait) le propos ici
On en conclut facilement que 30 octets en mémoire représentent 1 ligne, puisque 8x30 = ... 240 ! La largeur de l'écran des TI92/v200, quel hasard ! ...
Et pour les TI89 alors ? Eh bien, pour chaque ligne, il y a 20 octets utilisés (8x20 ...) et les 10 octets suivants ne "servent à rien", en tout cas les modifier n'a aucune incidence sur l'écran.
Voilà pour le codage en mémoire, passons maintenant au scrolling
Scrolling, haut-basD'après ce qui a été dit dans le dernier paragraphe, il est facile d'en déduire comment faire pour "scroller" d'une ligne vers le haut ou d'une ligne vers le bas : il suffit simplement de "décaler tout de 30 octets"
Pour le scrolling vers le haut par exemple, les octets "+0 à +30" seront perdus (la notation est faite exprès), ceux de "+30 à +60" se retrouveront en "+0 à +30" etc ... pour chaque ligne. Et on applique exactement le même principe pour le scrolling vers le bas, de l'autre côté.
Pour cela, on aura donc juste besoin d'une instruction :
memcpy, qui s'utilise de la façon suivante : memcpy(destination , source , nbre_d_octets_a_copier)
Avec du code, cela donne pour le scrolling vers le haut :
#define uchar unsigned char /* evite de devoir se trimballer des unsigned char, oui je suis flemmard 
#define SCR_ADDR 0x4c00 /* constante : adresse de base de l'ecran */
void scroll_up()
{
uchar *screen_addr = (uchar *)SCR_ADDR; /* adresse de base de l'ecran */
uchar *addr;
uchar i;
for(i=1;i {
addr = screen_addr + 30*i; /* recupere l'adresse du premier octet de la ligne courante */
memcpy(addr-30,addr,30); /* copie les 30 octets de la ligne courante sur la ligne d'au-dessus */
}
}
Pas très compliqué, maintenant le scroll à gauche et à droite :
Scrolling, gauche/droiteLe scrolling gauche/droite est un poil plus compliqué, cette fois il va falloir faire des décalages de bits et des opérations binaires (ou binaire, ou le symbole | (1 seul suffit ...)).
Le principe cette fois est de prendre chaque octet (donc chaque groupe de 8 pixels), faire un décalage de 1 bit vers la gauche (ou la droite) (chaque groupe de 8 pixels sera alors décalé de 1 pixel ...). Oui mais wait, que faire du bit le plus à gauche (ou à droite) de chaque groupe ? Le pixel correspondant sera allumé ou éteint selon le pixel qui est à sa droite ou à sa gauche, il faut donc récupérer le bit de poids fort de l'octet suivant (scroll gauche) ou le bit de poids faible de l'octet précédent (scroll droite)
On doit donc appliquer ce principe aux 30 octets de chaque ligne :
- Décalage d'un bit vers la gauche de chaque octet (revient à faire une multiplication par 2, pour le faire à la main, convertissez le nombre en binaire, c'est un
unsigned char donc entre 0 et 255, ça tient sur 8 bits, puis décalez tout d'un cran vers la gauche, le bit le plus à gauche étant perdu)
- Retenue du bit de poids fort (ou de poids faible) de l'octet suivant (précédent)
- Ou logique avec l'octet actuellement traité
Ce qui donne pour le scrolling à gauche ce que vous avez vu quelques posts plus haut :
#define uchar unsigned char
void scroll_left()
{
uchar ligne,col,next;
uchar *screen_addr;
/* screen_addr contient l'adresse de depart de l'ecran (0x4c00) */
screen_addr = (uchar *)0x4c00;
for(ligne=0;ligne {
for(col=0;col {
/* decalage de 1 bit vers la gauche (1 pixel vers la gauche) */
*screen_addr = *screen_addr
/* recupere le bit de poids fort (1er pixel de l'octet suivant) */
next = *(screen_addr + 1);
next = (next 7) 1;
/* modifie le dernier pixel de l'octet en cours selon la valeur du bit de poids fort de l'octet suivant */
*screen_addr = *screen_addr | next;
/* prochain octet */
screen_addr ++ ;
}
/* saute le 30eme octet de la ligne */
screen_addr ++ ;
}
}
petit arrêt sur les lignes :
next = *(screen_addr + 1);
next = (next 7) 1;
*screen_addr = *screen_addr | next;
la première ligne permet de récupérer l'octet suivant, la seconde fait un décalage de 7 bits vers la droite pour que le bit le plus à gauche (bit de poids fort, MSB) se retrouve tout à droite. On aurait aussi pu faire (next On a ainsi le bit de poids fort (0 ou 1) puis on fait un "ou logique", c'est-à-dire que le bit de poids faible de l'octet en cours vaudra 1 si le bit de poids fort de l'octet suivant est à 1 (s'il vaut 0, 0 | 0 = 0 ...)
Compliqué ? En schéma, cela donnerait :
(désolé pour la qualité, c'est fait avec paint et j'étais en mode flemmard
)Le scrolling à droite se fait selon le même principe que le scrolling à gauche.
Vous savez maintenant faire un scrolling dans les 4 directions (en principe). Ce tuto a donc atteint son but et donc se termine ici. Posez vos questions si vous en avez

Bah zut alors, je parle trop et mon mini-tuto s'est finalement transformé en vrai tuto

Bon bref, voilà l'explication, si vous avez des questions/remarques, allez-y !