Accueil

CPC


 Dev C sur CPC :

  • le C sur CPC
  • SDCC débuter
  • fichier BAT pour compiler
  • Dessiner Sur CPC
  • Optimiser le dessin
  • Ecrire du texte
  • Lire un fichier
  • Ecrire un fichier
  • Swap d'écran
  • CLS ultra rapide
  • H line
  • Attaquer le CRTC
  • Full Overscan
  • Put pixel très rapide
  • Afficher une image
  • Slide show 1
  • Bézier
  • faire un fichier pour Bézier

  • Quelque fonctions utile

  • Animation
  • 3D
  • Raster
  • Manche a balais

    Le plan du Site

  •  
      Ici les nouvelle du site  
     
    Recherche ?
    Saissisez un mot clé

     
      Quelques chiffres
    Visiteurs:4526
    Visiteurs aujourd'hui:2
     
     
    Me contacter
    Donnez votre avis
     
    Le site de Steph : Le CPC

    Afficher une image


    Alors la afficher une image n'a rien de très compliqué, surtout ci celle ci n'est pas compressé.
    Bon ok, sous basic pour charger une image il suffit de faire un LOAD"file",49152, un ,49152 ??? oui 49152 = C000, l'adresse de départ de l'écran...

    Donc en C il suffit de faire la même chose, on charge notre fichier image à l'adresse C000 et l'image s'affiche, mais bien souvent on n'a pas utilisé les couleurs par défaut du CPC, on les a redéfini pour notre image. Il faut donc avant changer les encres, mais il faut faire un code spécifique pour chaque image.
    Ce qui serais bien mieux se serais de lire les couleurs en même temps que l'image, mais ces informations ne sont pas présentent dans l'image. Par contre on peut les avoir avec un autre fichier qui est bien souvent avec l'extension .PAL. Attention, tous les fichiers .PAL ne sont pas forcement identique, la on va voir les fichiers .PAL généré avec OCP art studio, ConvImgCpc, JavaPaint,...

    Explication :
    Ce fichier comporte le mode d'écran utilisé, la palette est bien d'autre choses, nous n'allons nous intéressé qu'a une petite partie du fichier, en effet il permet de sauver des animations de couleurs, les encre exclue, protégé,...
    Le 1er octet c'est le mode d'écran, cela nous intéresse, les 2 octets suivant non, c'est pour l'animation de couleur. Ensuite on a un tableau de 16 * 12 pour les couleurs, puis 12 octets pour la couleur du border, puis 32 octets d'on on ne s'occuperas pas !.
    Un mot sur les couleurs sauvé, on ne peut pas les utiliser comme cela avec les fonctions systèmes car c'est les valeurs pour le CRT qui est directement sauvé, comme la on utilise les fonctions système pour changer les couleur, il faut donc les transformer, pour cela on vas utiliser un tableaux.
    Voici donc le code pour utiliser les données en mémoire venant d'un fichier .PAL :
    const unsigned char CpcVGA[ 28 ] = {84,68,85,92,88,93,76,69,77,86,70,87,94,64,95,78,71,79,82,66,83,90,89,91,74,67,75,0};
    
    void main()
    {
    	char* BufPal;
    
    	unsigned char i;
    	unsigned char j;
    
    	
    	// chargement du fichier .pal
    	ReadFileBin( "001.pal", 0x4000);
    	BufPal = (char*)((unsigned int)0x4000);
    	// met le bon mode
    	if ( BufPal[0] == 0 )
    		SCR_SET_MODE0_s;
    	if ( BufPal[0] == 1 )
    		SCR_SET_MODE1_s;
    	if ( BufPal[0] == 2 )
    		SCR_SET_MODE2_s;
    	
    	// met les couleurs
    	BufPal = (char*)((unsigned int)0x4000+3);
    	for ( i = 0; i < 16; i++ )
    	{
    		for ( j = 0; j < 27; j++ )
    		{
    			if ( BufPal[ i*12 ] == CpcVGA[ j ] )
    			{
    				SetColor_s( i, j );
    			}
    		}
    	}
    	
    	// chargement de l'images non compresse.
    	ReadFileBin( "001.SCR", 0xC000);
    
    	// attente d'une touche
    	KM_WAIT_CHAR_s;
    }
    

    Ici il n'y a pas toute les fonctions, il faut la lecture du fichier, mettre les couleurs, les modes, ... tout ceci est dans le ZIP final.

    Au vue de la capacité standard des disquettes du CPC (je vous le rappelle, c'est 178Ko) on ne pourra mettre que 178Ko / 16Ko (oui une image fait 16Ko !) donc 11 images, il reste un reliquat de 2Ko pour mettre notre programme. Donc si le programme pour afficher les images fait plus de 2Ko, on ne mettras que 10 images sur un face de disquette.

    Il faut bien avouer que l'affichage de l'image n'est pas trop super, elle s'affiche quand elle se charge et vue la gestion mémoire de la vidéo, on voie l'image s'afficher 1 ligne sur 8, on vas voire pour faire un peut mieux.
    Première solution, avant de charger l'image on passe l'affichage en la vidéo en 0x4000, on charge la palette et l'image en 0xC000 et on rebascule l'affichage vidéo en 0xC000, ce qui fait que notre image s'affiche d'un coup.
    Mais avec cette il y a un petit problème quand même, pendant que l'image se charge, on a un écran vide, a moins de gérer le chargement à différent endroit en fonction de la page vidéo affiché.
    On vas donc faire apparaitre notre image d'autre façon, avec comme seul contrainte de la charger en 0x4000 et affiché en 0xC000.
    Le plus classique c'est faire apparaitre l'image de haut en bas ou de bas en haut, voici le code :

    	// 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 al ligne
    		iAdr = ( y >> 3 ) * 80 + ( y & 7 ) * 0x800;
    		
    		for (x = 0; x<80; x++)
    		{
    			BufScr[iAdr+x] = BufDep[iAdr+x];
    		}
    	}
    
    	KM_WAIT_CHAR_s;
    	CLS_WithPile();
    	
    	// affichage de l'image en partant du bas de l'image vers le haut
    	for (yi = 199; yi>=0; yi--)
    	{
    		// calcule de l'adresse de debut de al ligne
    		iAdr = ( yi >> 3 ) * 80 + ( yi & 7 ) * 0x800;
    		
    		for (x = 0; x<80; x++)
    		{
    			BufScr[iAdr+x] = BufDep[iAdr+x];
    		}
    	}
    

    On peut faire la même chose de droite à gauche ou inversement :

    	// 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 al ligne
    			iAdr = ( y >> 3 ) * 80 + ( y & 7 ) * 0x800;
    			BufScr[iAdr+x] = BufDep[iAdr+x];
    		}
    	}
    
    
    	KM_WAIT_CHAR_s;
    	CLS_WithPile();
    	
    	// affichage de l'image en partant de la gauche vers la droite
    	for (xc = 79; xc>=0; xc--)
    	{
    		for (y = 0; y<200; y++)
    		{
    			// calcule de l'adresse de debut de al ligne
    			iAdr = ( y >> 3 ) * 80 + ( y & 7 ) * 0x800;
    			BufScr[iAdr+xc] = BufDep[iAdr+xc];
    		}
    	}
    

    On peut aussi faire apparaitre l'image par petits carré (aléatoire), la j'introduit la gestion pour les nombres aléatoire j'y reviens ensuite.
    La cela se complique un peut, on fait une matrice de carré, puis on les mélange et on affiche :

    	// 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*16;
    			Bufmatrice[mx][my].y = my*8;
    		}	
    	}
    
    	//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++)
    	{
    		WaitVbl();
    		
    		for(mx=0;mx<20;mx++)
    		{
    			for(y=0;y<8;y++)
    			{
    				// calcule de l'adresse de debut de la ligne
    				iAdr = ( (Bufmatrice[mx][my].y+y) >> 3 ) * 80 + ( (Bufmatrice[mx][my].y+y) & 7 ) * 0x800;
    
    				BufScr[iAdr+(Bufmatrice[mx][my].x/4)] = BufDep[iAdr+(Bufmatrice[mx][my].x/4)];
    				BufScr[iAdr+(Bufmatrice[mx][my].x/4)+1] = BufDep[iAdr+(Bufmatrice[mx][my].x/4)+1];
    				BufScr[iAdr+(Bufmatrice[mx][my].x/4)+2] = BufDep[iAdr+(Bufmatrice[mx][my].x/4)+2];
    				BufScr[iAdr+(Bufmatrice[mx][my].x/4)+3] = BufDep[iAdr+(Bufmatrice[mx][my].x/4)+3];
    			}
    		}
    	}
    

    Alors la gestion pour les nombres aléatoire, j'ai refait des fonctions m_randomize et m_random un peut comme le C (du moins pour les prototypes) car pour le reste c'est une adaptation pour CPC.
    Je ne vais pas rentré dans l'explication des nombres aléatoire, c'est en fait très très compliqué à faire (si si !!) car pour faire vite on n'a jamais des nombres aléatoire mais des suites ...
    Je suis partit du timer du CPC pour faire les nombres aléatoire, quand on appel la méthode m_randomize, je conserve l'octet de poids fort que nous fournis le timer du CPC.
    Puis à chaque fois que l'on appel la méthode m_random je fait un calcule super savant (la c'est du 4ème ou 5ème degré !!), je reprend le poids fort du timer du CPC et je le multiplie pas celui sauvé avant, puis un modulo avec la valeur max.
    On a donc rien d'aléatoire en fait, mais cela vas nous convenir, vous pouvez trouver bien d'autre méthode pour faire cela ....
    Pourquoi ce n'est pas vraiment des nombre aléatoire ?
    Car quand vous allumer le CPC, sont timer part de 0 et tous les 1/300 de seconde s'incrémente de 1...
    Dans notre cas, si vous allumer le CPC, exécuter le programme vous aurez donc une suite de nombres.
    La il faut être très fort mais si vous allumer votre CPC, exécuter votre programme et que cela tome sur les même 1/300 de seconde que le 1er essai, vous aurez la même suite de nombre que la 1er fois !!!

    Un dernier effet pour afficher une image, l'effet roulo :
    unsigned char Roulo[12]={62,58,54,50,46,43,40,37,35,33,32,31};
    
    	hroulo = 12;//23;
    	for(i=0;i> 3 ) * 80 + ( yr & 7 ) * 0x800;
    				iAdrd = ( y+i >> 3 ) * 80 + ( y+i & 7 ) * 0x800;
    				for (x = 0; x<80; x++)
    				{
    					BufScr[iAdrd+x] = BufDep[iAdr+x];
    				}
    				
    			}
    		}
    		
    		// calcule de l'adresse de debut de la ligne
    		iAdr = ( y >> 3 ) * 80 + ( y & 7 ) * 0x800;
    		for (x = 0; x<80; x++)
    		{
    			BufScr[iAdr+x] = BufDep[iAdr+x];
    		}
    		
    	}
    

    Voila, il n'y a plus qu'a utiliser, chercher d'autre effet, mais y'a plus de secret pour afficher une image avec sont fichier .PAL sur CPC.
    Il ne reste plus qu'a faire des images pour faire un SlideShow.
    Le seul inconvénient, on ne peut pas mettre plus de 11 images sur une face de disquette... sinon il faut compresser... c'est pour l'article suivant.


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