Developpez.com

Club des développeurs et IT pro
Plus de 4 millions de visiteurs uniques par mois

Developpez.com - Delphi
X

Choisissez d'abord la catégorieensuite la rubrique :


Le mode graphique

Date de publication : 01/01/2001 , Date de mise à jour : 01/11/2005

Par Paul Toth (Site)
 

Le mode graphique.



Nous avons vu précédemment comment allouer une console et comment déterminée si elle est active. Passons aux choses sérieuses, l'activation du mode graphique.

Tout d'abord, il nous faut des privilèges pour dialoguer avec le hardware, moi je travaille sous root, c'est pas une bonne idée sur un serveur, mais ici on parle de mode graphique, de jeux et pas de serveur :)

Avant toute chose, on va déterminer si le PC et bel et bien équipé d'une carte compatible VGA...ça peut paraitre superflue, mais dans le monde Linux on ne sait jamais...et c'est une bonne introduction au dialogue avec le hardware.

Pour dialoguer avec la carte vidéo, il nous faut adresser les port de $3B4 à $3DF.
 ioperm($3B4,$3DF-$3B4+1,1); // demande l'accès aux port $3B4 à $3DF
Maintenant on va pouvoir ressortir les vieux manuels de programmation DOS :)
  function IsVGA:boolean; assembler;
   asm
    mov dx,$3c8
    in al,dx;  mov cl,al // get original value
    not al;    out dx,al // store not(value)
    in al,dx;  mov ch,al // re-read value
    mov al,cl; out dx,al // restore original value
    mov al,true
    not cl;    sub cl,ch // compare the two values
    jz @ok
     mov al,false
    @ok:
   end;
Et oui ! on a beau être dans un univers 32 bits protégé, le même code fonctionne sous DOS et sous Linux :)
Remarquez, c'est un peu normal vu que la carte graphique ne se préoccupe pas du mode de fonctionnement du processeur...

Le code de détection n'est pas parfait, il renvoie FALSE sur un "Cirrus Laguna 3D" pourtant compatible VGA, prévoyez donc un mode passthrough (une option -vga sur la ligne de commande par exemple) !

Il nous faut également un accès à la RAM video (sous Borland Pascal on utilise Mem[SegA000:$0000]).
Sous Linux, rien de plus simple, la RAM est vue comme un fichier :)
 mem:=open('/dev/mem',O_RDWR);
précisons que l'on veut accèder au segment $A000 :
 SegA000:=mmap(nil,$FFFF,PROT_READ or PROT_WRITE,MAP_SHARED,mem,$A0000);
On donne ici l'adresse linéaire 32bits ($A0000) et pas le segment du mode réel ($A000).

Le reste ne s'invente pas, même avec "PC Interdit" et "La Bible du PC" j'ai du mal à interpréter tous les paramètres à envoyer à la carte, on les trouve cependant sur le net dans la rubrique "passer en mode graphique sans le BIOS"...

Et oui, on ne peut pas invoquer l'interruption 10h ! Elle est détournée par le mode protégé et ne correspond plus du tout au BIOS de la carte video !

Vous trouverez le code complet sur dans ma version KCyber de la démo de Jacco.

Il me reste à préciser que le switching doit maintenant prendre en charge le passage en mode graphique lors de l'activation de la console, et le retour au mode texte quand on la quitte...même si le nouvel écran est graphique (XWindow par exemple).
procedure OnSwitch(signal:integer); cdecl;
 begin
  case signal of
   OnEnter: begin
    if GraphicMode then begin // boolean déterminant si la console est en mode graphique
     ScreenOff; // désactive l'affichage vidéo avant de changer le mode graphique
     SetMode(Mode13h); // passer en mode 320x200
     LoadScreen(OffScreen); // OffScreen contient une copie de l'écran graphique
     video:=SegA000; // les accès mémoire se feront maintenant directement en RAM video
     ScreenOn; // réactiver l'affichage écran
    end;
    ioctl(vc, VT_RELDISP, pointer(VT_ACKACQ)); 
    focus:=true;
   end;
   OnLeave: begin
    if GraphicMode then begin
     ScreenOff;
     SaveScreen(OffScreen);  // sauvegarde de l'écran graphique
     video:=@OffScreen.video;  // les accès mémoire se feront maintenant dans un buffer interne
     LoadScreen(CrtScreen); // restore le texte et les FONT du mode texte
     SetMode(Mode03h);  // passage en mode texte 80x25
     ScreenOn;
    end;
    ioctl(vc, VT_RELDISP, pointer(1)); 
    focus:=false;
   end;
  end;
 end;
Mon unité VGA utilise un buffer interne "OffScreen" qui est utilisé à la place de la RAM video lorsque la console n'est pas active; le pointer "video" pointe donc selon le cas sur la RAM video ou sur ce buffer.

"CrtScreen" est initialisé lors du passage en mode graphique, il contient une copie de la RAM video du mode texte, on sauvegarde à la fois le texte et les polices de caractères.

Voilà, vous pouvez télécharger un projet reprenant les exemples de ce tutorial.

Retrouvez le source complet de KCyber sur mon site Look Inside.



Valid XHTML 1.1!Valid CSS!

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2005 Paul Toth. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Responsables bénévoles de la rubrique Delphi : Gilles Vasseur - Alcatîz -