CODINGSDCC TUT'S PAR STEPHBB75 ★ Slide Show ★

Sdcc - 23 - Slide ShowCoding Sdcc Tut's Par Stephbb75

Si vous avez lu l'article "Afficher une image", on vas repartir de ce que l'on y a vue pour faire un Slide Show ( en bon français un Diaporama ... ca fait moins cool :-) )

Le plus compliqué là, c'est les images à afficher, j'ai choisi de belle mécanique...mais les goûts et les couleurs ...

Donc, j'ai repris chaque effets dans l'article précédent pour en faire une fonction pour chaque. Au passage j'ai fait quelques modifications / optimisation.
Premier changement, pour le calcule de l'adresse du Y à l'écran, j'ai fait une fonction, cela évite de dupliquer ce code dans toutes les fonctions (un petit gain de place), je ne l'est pas fait pour cette article, mais il faudrait l'écrire en ASM, cela serais bien plus rapide...
Pour les 4 effets d'affichage par le haut, bas, droite et gauche pas de changement :

//
// Fonctions pour les différents effets d'affichage d'une image
//
int CalYAdr( unsigned char y )
{
return ( y >> 3 ) * 80 + ( y & 7 ) * 0x800;
}

void AffHautBas(char* BufScr, char* BufDep)
{
unsigned char y;
unsigned char x; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
int iAdr; // adresse de l'écran (relatif à BufScr)

// Affichage de l'image en partant du haut de l'image vers le bas
for (y = 0; y<200; y++)
{
// Calcule de l'adresse de debut de la ligne
iAdr = CalYAdr( y );

for (x = 0; x<80; x++)
{
BufScr[iAdr+x] = BufDep[iAdr+x];
}
}
}

void AffBasHaut(char* BufScr, char* BufDep)
{
int y;
unsigned char x; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
int iAdr; // adresse de l'écran (relatif à BufScr)

// Affichage de l'image en partant du bas de l'image vers le haut
for (y = 199; y>=0; y--)
{
// calcule de l'adresse de debut de la ligne
iAdr = CalYAdr( y );

for (x = 0; x<80; x++)
{
BufScr[iAdr+x] = BufDep[iAdr+x];
}
}
}

void AffDroiteGauche(char* BufScr, char* BufDep)
{
unsigned char y;
unsigned char x; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
int iAdr; // adresse de l'écran (relatif à BufScr)

// Affichage de l'image en partant de la droite vers la gauche
for (x = 0; x<80; x++)
{
for (y = 0; y<200; y++)
{
// Calcule de l'adresse de debut de la ligne
iAdr = CalYAdr( y );
BufScr[iAdr+x] = BufDep[iAdr+x];
}
}
}

void AffGaucheDroite(char* BufScr, char* BufDep)
{
unsigned char y;
char x; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
int iAdr; // adresse de l'écran (relatif à BufScr)

// Affichage de l'image en partant de la gauche vers la droite
for (x = 79; x>=0; x--)
{
for (y = 0; y<200; y++)
{
// Calcule de l'adresse de debut de la ligne
iAdr = CalYAdr( y );
BufScr[iAdr+x] = BufDep[iAdr+x];
}
}
}


Pour l'affichage par carré, j'ai un peut modifier la fonction qui retourne un nombre aléatoire, en plus de prendre les valeurs de poids faible du timer, j'utilise la valeur du registre R du Z80...

// gestion pour les nombres aléatoire
// En fait c'est pas vraiment des nombres aléatoire, c'est plus une suite ...
// c'est bien compliqué à expliquer ici....
// j'ai donc fait un truc simple pour le CPC
// je part du GetTime et utilise aussi la valeur du registre R du Z80....

unsigned char rStart;
// initalisation pour les nombre aléatoire
void m_randomize()
{
// on appel la fonction GetTime_s mais on s'en fout de sont retour,
// ce qui m'intéresse c'est la variable global char2 que cette fonction utilise...
GetTime_s();

rStart = char2;
}

char regR;
void getR()
{
__asm
LD HL, #_regR
LD A, R
LD (HL), A
__endasm;
}

// récupére un nombre "aléatoire" compris entre 0 et valmax
// il ne faut pas mettre 255 ou 0 pour valmax
unsigned char m_random(unsigned char valmax)
{
unsigned char rRet = 255;

while (rRet > valmax)
{
// on appel la fonction GetTime_s mais on s'en fout de sont retour,
// ce qui m'intéresse c'est la variable global char2 que cette fonction utilise...
getR();
GetTime_s();

rRet = (unsigned char)((int)((rStart * char2) / regR ) % valmax);
}

return rRet;
}


Pour la partie d'affichage en carré, seul modif, on utilise une fonction memcpy optimisé pour le CPC (Z80 en fait), qui vas bien plus vite que si on utilisais le memcpy de la biblio standard du C proposé par SDCC.
La fonction memcpy optimisé :

// fonction de copie mémoire optimisé pour le CPC
// bien plus rapide que la fonction de la bibli stendard
void m_memcpy(void* dest, void* src, int lenght)
{
__asm

push HL
push DE
push BC

LD E, 4(IX) ; (6) HL = adresse de départ
LD D, 5(IX) ; (6)

LD L, 6(IX) ; (6) DE = adresse de destination
LD H, 7(IX) ; (6)

LD C, 8(IX) ; (6) BC = nombre d'octets
LD B, 9(IX) ; (6)

LDIR ; (5) Recopie de bloc

pop BC
pop DE
pop HL

__endasm;
}


Voici donc la fonction pour l'affichage en caré :

void AffCare(char* BufScr, char* BufDep)
{
unsigned char y;
unsigned char x; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
int iAdr; // adresse de l'écran (relatif à BufScr)

// pour effect carre
unsigned char my;
unsigned char mx; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
char ir,jr;

// affichage de l'image par carré (aléatoire):
// les blocs font 16*8, il y a donc 20 blocs (4 octets par bloc) en X et 25 bloc en Y
// on vas faire une matrice de bloc en mémoire

//Initialise la matrice
for(my=0;my<25;my++)
{
for(mx=0;mx<20;mx++)
{
Bufmatrice[mx][my].x = mx<<4;
Bufmatrice[mx][my].y = my<<3;
}
}

//Melange la matrice
m_randomize();
for(my=0;my<25;my++)
{
for(mx=0;mx<20;mx++)
{
ir=m_random(19); //Bloc aleatoire
jr=m_random(24);

//Echange avec un autre bloc
BufmatriceTMP.x = Bufmatrice[mx][my].x;
Bufmatrice[mx][my].x = Bufmatrice[ir][jr].x;
Bufmatrice[ir][jr].x = BufmatriceTMP.x;

BufmatriceTMP.y = Bufmatrice[mx][my].y;
Bufmatrice[mx][my].y = Bufmatrice[ir][jr].y;
Bufmatrice[ir][jr].y = BufmatriceTMP.y;
}
}

//Affiche la matrice
for(my=0;my<25;my++)
{
for(mx=0;mx<20;mx++)
{
for(y=0;y<8;y++)
{
// calcule de l'adresse de debut de la ligne
iAdr = CalYAdr( (Bufmatrice[mx][my].y+y) );
m_memcpy( BufScr+iAdr+(Bufmatrice[mx][my].x/4), BufDep+iAdr+(Bufmatrice[mx][my].x/4), 4 );
}
}
}
}


La plus grosse modification c'est pour l'affichage avec l'effet roulo, la on utilise le m_memcpy ce qui fait gagner bien du temps, et le roulo est un peut plus haut, ce qui donne un effet un peut mieux.

void AffRoulo(char* BufScr, char* BufDep)
{
unsigned char y;
char x; // attention, c'est pas les pixels mais les octets qui sont utilisé ici !!!
unsigned int iAdr; // adresse de l'écran (relatif à BufScr)

// pour l'effec roulo
unsigned char yr,i;
unsigned int iAdrd; // adresse destination
unsigned char hroulo; // hauteur du roulo

unsigned char Roulo_t[23];

// affichage en roulo
hroulo = 23;
for(i=0;i> 3 ) * 80 + ( yr & 7 ) * 0x800;
iAdrd = ( y+i >> 3 ) * 80 + ( y+i & 7 ) * 0x800;

// copie la ligne
m_memcpy( BufScr+iAdrd, BufDep+iAdr, 80 );
}
}

// calcule de l'adresse de debut de la ligne
iAdr = CalYAdr( y );
// copie la ligne
m_memcpy( BufScr+iAdr, BufDep+iAdr, 80 );
}
}


Voila pour les effets, ils sont pret...

On ne vas rien changer au chargement des palettes et des images, le code reste identique à celui de l'article précédent.
Par contre je vais implémenter le fait de mettre un effet aléatoirement à l'image que l'on vas afficher, cela permet de le changer à chaque fois, vous pouvez lancer le Slide Show, les images apparaitront jamais 2 fois de la même façon ! (vous pouvez quand même avoir 2 images de suite avec les même effet, mais si vous relancer le Slide, vous n'aurais pas les même effets ...)
Autre choses, pendant que l'on regarde une image, on charge la suivante, un petit gain de temps !
Sinon, juste comme cela, on appuie sur une touche pour passer à l'image suivante, mais la touche "ESC" permet de quitter directement le Slide Show.
Voici donc le main de notre programme :

void main()
{
char* BufDep; // buffer de départ
char* BufScr; // buffer de l'écran
unsigned char curFile;
unsigned char RendEffet;
char pressChar;

BufDep = (char*)((unsigned int)0x4000);
BufScr = (char*)((unsigned int)0xC000);

// initalisation pour les nombres aléatoite
m_randomize();

curFile = 0;

// on charge les 1er fichiers images
// chargement du fichier .pal
ReadFileBin( (char*)FileP[curFile], 0x2000);
// chargement de l'images non compresse. On la charge en 0x4000
ReadFileBin( (char*)FileS[curFile], 0x4000);

curFile++;

while ( 1 )
{
// on applique la palette
ApplyPal();

// on fait l'effet d'afichage de façon aléatoire...
RendEffet = m_random(7);

switch( RendEffet )
{
case 0:
case 1: AffHautBas(BufScr, BufDep);
break;
case 2: AffBasHaut(BufScr, BufDep);
break;
case 3: AffDroiteGauche(BufScr, BufDep);
break;
case 4: AffGaucheDroite(BufScr, BufDep);
break;
case 5: AffCare(BufScr, BufDep);
break;
case 6: AffRoulo(BufScr, BufDep);
break;
}

// si le fichier à lire est vide, on quite la boucle...
if ( FileP[curFile] == 0 )
{
// on attent quand même une touche...
KM_WAIT_CHAR_s;
break;
}


// on charge le fichier suivent ...
// chargement du fichier .pal
ReadFileBin( (char*)FileP[curFile], 0x2000);
// chargement de l'images non compresse. On la charge en 0x4000
ReadFileBin( (char*)FileS[curFile], 0x4000);

curFile++;

// une touche de pressé ....
pressChar = GetChar();
while ( pressChar == 0 )
pressChar = GetChar();

// esc, on quite
if ( pressChar == -4 )
break;

pressChar = 255;
}

}


Et voila, on a fait notre premier Slide Show. Comme dit dans l'article précédent, les images ne sont pas compressé, donc on ne peut pas en mettre beaucoup sur une face de disquette, la on en a 9 (seulement ! ? )

Voila, comme d'hab, le tout se trouve dans se ZIP, bon SlideShow ... Diaporama ;-)

La suite ... utiliser des images compressées... mais c'est la suite ...

stephbb75

★ ANNÉE: 2013
★ AUTEUR: Stephbb75

Page précédente : Sdcc - 22 - Afficher uneImage

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Sdcc - 17 - 3D - Trace Points
» Coding » Sdcc - 22 - Afficher uneImage
» Coding » Sdcc - 02 - Utilisation de Sdcc
» Coding » Sdcc - 09 - Cls Ultra Rapide
» Coding » Sdcc - 12 - Put Pixel Tres Rapide
» Coding » Sdcc - 08 - Swap d'Ecran
Je participe au site:

» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop
Page créée en 258 millisecondes et consultée 1937 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.