> TechDémo
PrograZine issue #8 - http://www.citeweb.net/discase/8/STAR.htm Edito Sommaire Contribution Contacts


Pratique: un StarField
par Sylvain Gaeremynck - 8 rue BEETHOVEN 59420 MOUVAUX
Debutant DOS Pascal
> fichiers attachés
star.pas




    Cet article est avant tout destine aux grands debutants qui veulent passer a la pratique (je sais la phrase est bete mais c'est un cap qui est parfois difficile a franchir). Nous allons donc mettre en oeuvre les structures apprises dans les initiations de Discase en Pascal pour creer sous DOS en mode 13h une petite animation.

    Important: Ne le faites pas sous Win95/98, il n' aime pas le 320*200*256 (NDLR: Ca passe quand même ...)

    Je m excuse d avance pour les fautes d orthographe.
>Le Mode 13h

     Ce mode correspond au mode graphique VGA 256 couleurs du DOS dont les dimensions sont 320 sur 200. Ce choix de mode est motive par le fait qu il est facile a programmer et que l on a pas besoin de plus pour de jolies choses. Pour l initialiser c est simple on appelle la fonction 13h de l interruption 10h.

    On a donc la procedure:
Procedure InitMode13;assembler;
asm
  Mov ax,0013h
  Int 10h
end;
l

    De meme on appellera la fonction 03h pour revenir au mode texte.
>Les Etoiles

     Pour faciliter le traitement des parametres de chaque etoile on va creer un enregistrement (record) qui contiendra les coordonnées x,y,z de chaque etoile sa vitesse et sa couleur. Et comme on veut pas qu une etoile on va creer un tableau d etoiles. En clair
Type
  Etoile = record
		x,y,z   : integer;
                col     : byte;
                vitesse : word
	   end;
  TEtoile = array[1..NbrEtoile] of Etoile;
l

    ou NbrEtoile est une constante.

    Ensuite il va falloir les afficher nos etoiles; il suffit de comprendre l adressage de la memoire du mode 13h: c est tres simple... ;-)
>L affichage En Mode 13h

     L ecran se presente comme un tableau de 320 sur 200 points. Ces points sont adresses lineairement c est a dire que pour modifier le point de coordonnees (160,100) a l ecran on le fera en modifiant le 160+320*100 points de la memoire. Il faut bien comprendre que l' on ecrit pas veritablement un point sur l ecran mais on en modifie la couleur. A l initialisation du mode l ecran est tout noir car tous les pixels sont noirs mais si on met la couleur rouge a la x+320*y position de la memoire video, le pixel deviendra rouge a l ecran.

     Le mode 13h peut afficher jusqu a 256 couleurs en meme temps donc elles sont codees sur 8 bit: la memoire video est un tableau d' octet. Il se trouve dans la memoire centrale de l ordinateur et demare a l adresse $0A000 et a une taille de 64000 octets.
l
  • On appelle rafraichisement la copie de la memoire video dans la memoire de la carte graphique, pour l' affichage.
  • Quel que soit le mode graphique la memoire video a une taille de 64 Ko. Cela pose donc des problemes lorsqu on a besoin de plus de memoire comme pour les modes SVGA... mais c est une autre histoire.

    Pascal permet d acceder directement a la memoire avec l instruction Mem, d ou la procedure:
Procedure PutPixel(x,y : integer;col : byte);
Begin
  If (x>=0) and (x<=320) and (y>=0) and (y<=200) then
  			Mem[$0a000: 320*y + x] := col
End;
l
Le test nous assure que le point de coordonnees (x,y) est affichable dans la zone qui nous concerne, ici l ecran.
>Comment je modifie la couleur?

    Pour cela il existe une interruption mais c est pas pratique. La methode la plus utilisee est la modification directe des ports (un port est un acces directe au hardware de l ordinateur). Une couleur sur ordinateur est composee de rouge, de vert et de bleu et est codee sur 16 bits en mode 13h. Chaque nuance est donc codee sur 5 bits ce qui fait 64 possibilites de 0 à 63. On choisit sa couleur en mettant son numero dans le port d' adresse $3c8 puis sur le port $3c9 on met les proportions de rouge, de vert et de bleu dans cet ordre.

    En pascal cela donne
Procedure Pr_Pal(i,r,v,b : byte);
begin
  Port[$3c8]:=i;
  Port[$3c9]:=r;
  Port[$3c9]:=v;
  Port[$3c9]:=b;
End;
l

    Si on veut que la couleur 12 soit un rouge intense on appellera: Pr_Pal(12,63,0,0);

    Cela permet entre autre de faire des animations en temps reel, juste en modifiant les couleurs des pixels affiches a l ecran (c est la base des plasmas).

    Dans le programme j ai choisit d utiliser les nuances de gris pour les etoiles. La palette est donc initialisee par:
For i:=0 to 255 do Pr_Pal(i , i shr 2 , i shr 2 , i shr 2);
l

    ou i shr 2 <=> i div 4
>L animation des etoiles

     L animation est assez basique. J affiche une etoile a une position en mettant le pixel correspondant a la couleur de l etoile puis on l efface en mettantsa couleur a zero (i.e noir).

     Pour faire avancer nos etoiles, on incrementera la cote z de l etoile de sa vitesse a chaque fois.Le passage des coordonnees 3d en 2d se fait tres simplement avec le theoreme deThales:
X_2d = X_3d div Z_3d
Y_2d = Y_3d div Z_3d
l

    Cette formule est un peu simplifiee mais conviendra parfaitement dans ce cas.

    Voila vous savez tout ce qu il faut savoir pour realiser votre starfield 3d.

    Avec le code source joint, j ai obtenu une animation ,de 200 etoiles, fluide sur un 486 sx 25.
l
  • Il y a une procedure balayage dans le programme. Celle-ci sert a synchroniser l affichage avec le retour de balayage du rayon cathodique, sinon on obtient des pixels de couleur rose (sur mon écran Tatung et ma vieille Trident).
  • Il y a deux procedures qui font appelle a l interruption 16h fonction 01h du BIOS. Elles permettent de verifier si une touche du clavier a ete appuyee ou non. Elles sont obligatoires sur les Pentium II car l unite crt de Borland Pascal 7.0 plante.
  • A partir d une certaine cote plutot que d afficher un pixel, le programme affiche une croix. Il parait que c est plus joli. Si vous n en voulez pas les modifications a apporter sont mineures donc debrouillez vous.
>Ameliorations possibles

     Ce programme n est pas du tout optimise mais la vitesse obtenue est suffisante pour une introduction. Pour ceux que ca interesse on pourrait augmenter la rapidite en utilisant des pointeurs et un buffer. On affiche les etoiles dans le buffer puis on le copie dans la memoire video, on le vide etc... On peut meme prevoir un fond d etoile fixe ou une planete pour faire joli.

    On pourrait aussi reecrire les routines d affichage en assembleur.

    Une effet interessant serait de d ajouter un coefficient de rotation. On avancerait toujours selon l axe des z mais les etoiles auraient un mouvement de rotation autour de l axe des abscisses, des ordonnées ou de la cote voire tous en meme temps. Pour cela relisez l introduction de Nao sur les tranformations 3d a l aide de matrices.

     Pour toute suggestion ou commentaire
Sylvain Gaeremynck
8 rue BEETHOVEN
59420 MOUVAUX
l
Cet article est la propriété de Sylvain Gaeremynck. L'auteur et la rédaction du magazine déclinent toutes responsabilités vis-à-vis des conséquences que pourrait entraîner ce document.