home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / pc / CONTRSRC.ZIP / SRC / SETUP / WIN.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-09-29  |  50.4 KB  |  1,082 lines

  1. {**************************************************************************
  2. *  W I N : une unité de routines permettant l'accès direct à la mémoire   *
  3. *          vidéo et la gestion de fenêtres                                *
  4. **-----------------------------------------------------------------------**
  5. *  Auteur           : MICHAEL TISCHER                                     *
  6. *  Développé le     : 17.03.1989                                          *
  7. *  Dernière MAJ     : 21.09.1989                                          *
  8. **************************************************************************}
  9.  
  10. unit Win;
  11.  
  12. interface
  13. uses Dos, Crt;      { Inclusion des unités nécessaires }
  14.  
  15. {-- Déclaration des fonctions et procédures susceptibles d'être  ---------}
  16. {-- appelées par un autre programme                                 ------}
  17.  
  18. function  VG            ( Offset : integer ) : byte;
  19. function  VD            ( Offset : integer ) : byte;
  20. function  VH            ( Offset : integer ) : byte;
  21. function  VB            ( Offset : integer ) : byte;
  22. function  WinOpen       ( x1, y1, x2, y2 : byte ) : integer;
  23. function  WinOpenShadow ( x1, y1, x2, y2 : byte ) : integer;
  24. function  WinInFront    ( Key : integer ) : boolean;
  25. function  WhereX        : integer;
  26. function  WhereY        : integer;
  27. function  WinGetChar    ( Colonne, Ligne : byte ) : char;
  28. function  WinGetCol     ( Colonne, Ligne : byte ) : byte;
  29. procedure WinWrite2View ( Doit : boolean );
  30. procedure WinPutChar    ( Colonne, Ligne : byte; Caractere : char;
  31.                           Couleur : byte );
  32. procedure WinSetCursor  ( Colonne, Ligne : byte );
  33. procedure WinDefCursor  ( Debut, Fin : byte );
  34. procedure WinHideCursor;
  35. procedure WinBlockCursor;
  36. procedure WinLineCursor;
  37. procedure WinSetView    ( x1, y1, x2, y2 : byte);
  38. procedure WinGetView    ( var x1, y1, x2, y2 : byte );
  39. procedure GotoXY        ( X, Y : integer );
  40. procedure TextColor     ( Color : byte );
  41. procedure TextBackground( Color : byte );
  42. procedure ClrScr;
  43. procedure WinClose      ( ReDraw : boolean );
  44. procedure WinPrint      ( Colonne, Ligne, Couleur : byte; Sortie : string );
  45. procedure WinFill       ( x1, y1, x2, y2 : byte; Caractere : char;
  46.                           Couleur : byte );
  47. function  WinStRep      ( Caractere : char; Nombre : byte ) : string;
  48. procedure WinFrame      ( x1, y1, x2, y2, Cadre, Couleur : byte );
  49. procedure WinScrollDown ( x1, y1, x2, y2, Nombre, Couleur : byte );
  50. procedure WinScrollUp   ( x1, y1, x2, y2, Nombre, Couleur : byte );
  51. procedure WinScrollLeft ( x1, y1, x2, y2, Nombre, Couleur : byte );
  52. procedure WinScrollRight( x1, y1, x2, y2, Nombre, Couleur : byte );
  53. procedure WinMoveUp     ( Nombre : byte );
  54. procedure WinMoveDown   ( Nombre : byte );
  55. procedure WinMoveRight  ( Nombre : byte );
  56. procedure WinMoveLeft   ( Nombre : byte );
  57. procedure WinMove       ( x, y : byte );
  58. procedure WinColor      ( x1, y1, x2, y2, Couleur : byte );
  59.  
  60. {-- Constantes publiques  ------------------------------------------------}
  61.  
  62. const {-- les constantes suivantes représentent le contenu de VioCarte -}
  63.  
  64.       MDA       = 0;           {  MDA und HGC   }
  65.       CGA       = 1;
  66.       EGA       = 2;
  67.       EGA_MONO  = 3;           { EGA avec moniteur MDA }
  68.       VGA       = 4;
  69.       VGA_MONO  = 5;           { VGA avec moniteur analogique monochr. }
  70.       MCGA      = 6;
  71.       MCGA_MONO = 7;           { MCGA avec moniteur analogique monochr.}
  72.  
  73.       {-- Constantes pour la procédure WinFrame ---------}
  74.  
  75.       CAD_SIM    = 1;    { Cadre simple  }
  76.       CAD_DOU    = 2;    { Cadre double  }
  77.       CAD_POI    = 3;    { Cadre pointillé }
  78.       CAD_PLE    = 4;    { Cadre plein }
  79.  
  80.       NO_CLEAR     = 255;  { pour les procédures WinScroll }
  81.       WinOpenError = -1;   { Fenêtre impossible à ouvrir }
  82.       MAX_COLS     = 132;  { Certaines cartes VGA supportent 132 colonnes }
  83.  
  84.       {-- Couleurs ----------------------------------------------------}
  85.  
  86.       NOIR        =  0;
  87.       BLEU        =  1;
  88.       VERT        =  2;
  89.       CYAN        =  3;
  90.       ROUGE       =  4;
  91.       MAGENTA     =  5;
  92.       BRUN        =  6;
  93.       GRISCLAIR   =  7;
  94.       GRISFONCE   =  8;
  95.       BLEUCLAIR   =  9;
  96.       VERTCLAIR   = 10;
  97.       CYANCLAIR   = 11;
  98.       ROUGECLAIR  = 12;
  99.       MAGENTACLAIR= 13;
  100.       JAUNE       = 14;
  101.       BLANC       = 15;
  102.  
  103. {-- Variables globales également accessibles à d'autres programmes -----}
  104.  
  105. var Color : boolean;  { TRUE pour les cartes couleur }
  106.     VioCarte,         { Code décrivant la carte vidéo }
  107.     NbLig,           { Nombre de lignes d'écran }
  108.     NbCol    : byte;  { Nombre de colonnes d'écran }
  109.  
  110. {-- Constantes typées, publiques -------------------------------------}
  111.  
  112. const Write2View : boolean = TRUE;  { Pour que Writeln tienne compte des }
  113.                                     { limites de la zone de visualisation }
  114.       ShadowX    : byte = 2;        { Largeur d'une ombre en colonnes }
  115.       ShadowY    : byte = 1;        { Profondeur d'une ombre en lignes}
  116.  
  117. implementation
  118.  
  119. {-- Constantes internes au module ----------------------------------------}
  120.  
  121. const {-- Attribut de la fenêtre------------------------------------------}
  122.  
  123.       WIN_OMBRE = 1;       { Bit 0: La fenêtre n'a pas d'ombre }
  124.  
  125. {-- Déclarations de types internes au module -----------------------------}
  126.  
  127. type BPTR     = ^byte;   { Pointe sur un octet }
  128.  
  129.      VEL      = record   { Décrit un couple caractère-attribut }
  130.                   case boolean of      
  131.                     true  : ( Caractere, Attribut : byte );
  132.                     false : ( Contenu : word );
  133.                 end;
  134.  
  135.      VPTR     = ^VEL;   { Pointe sur un couple caractère-attribut }
  136.  
  137.      VELARRAY = array [0..9999] of VEL;  { Buffer de fenêtre }
  138.  
  139.      VELARPTR = ^VELARRAY;    { Pointe sur un buffer de fenêtre}
  140.  
  141.      WIPTR    = ^WINDES;      { Pointe sur un descripteur de fenêtre }
  142.  
  143.      WINDES   = record       { Descripteur de fenêtre }
  144.                   Attribut,  { Attribut de la fenêtre }
  145.                   Handle,    { Numéro servant de clé d'accès à la fenêtre }
  146.                   x1, y1,    { Coordonnées des coins de la fenêtre }
  147.                   x2, y2,
  148.                   ViewX1, ViewY1, { Coordonnées de la zone }
  149.                   ViewX2, ViewY2, { de visualisation }
  150.                   curc, curl    : byte; { Coordonnées du curseur avant
  151.                                           ouverture }
  152.                   lastwin,     { Lien avec la fenêtre précédente ...}
  153.                   nextwin       : WIPTR; { ...et avec la suivante  }
  154.                   buffer        : byte;   { Début du buffer de la
  155.                                             fenêtre }
  156.                 end;
  157.  
  158.      PTRREC   = record     { Permet d'accéder aux }
  159.                   Ofs : word;   { composants d'un pointeur }
  160.                   Seg : word;   { quel qu'il soit }
  161.                 end;
  162.  
  163.      HANDLES  = array [0..63] of byte; { Tableau de bits pour mémoriser }              
  164.                                        { les numéros des fenêtres }
  165.  
  166.      HANDPTR  = ^HANDLES;    { Pointe sur le tableau des numéros }
  167.  
  168. {-- Variables globales internes au module ----------------------------}
  169.  
  170. var VioSeg      : word;   { Segment de la mémoire vidéo }
  171.     LigneOfs   : integer; { Nombre d'octets dans une ligne }
  172.     WritelnX,      { Colonne d'affichage pour Writeln }
  173.     WritelnY,      { Ligne d'affichage pour Writeln }
  174.     vLigne,        { Position courante du curseur }
  175.     vColonne,
  176.     ViewX1,        { Coin supérieur gauche de la zone de visualisation  }
  177.     ViewY1,        { par rapport à la totalité de l'écran }
  178.     ViewX2,        { Coin inférieur droit de la zone de visualisation }
  179.     ViewY2      : byte;  { par rapport à la totalité de l'écran }
  180.  
  181.     WritelnPtr  : VPTR; { Pointe sur la position d'affichage de WinWriteln}
  182.     FirstWinPtr : WIPTR; { Pointe sur le premier descripteur de fenêtre }
  183.     ActBufPtr   : VELARPTR; { Pointe sur le buffer courant }
  184.     HaPtr       : HANDPTR;  { Pointe sur le tableau des numéros }
  185.  
  186. {-- Variables globales initialisées (constantes typées )    --------------}
  187.  
  188. const NbWin    : integer = 0;  { Nombre de fenêtres ouvertes }
  189.       ActWinPtr : WIPTR = nil;  { Pointe sur le descripteur courant }
  190.       WritelnCol: byte = $07;   { Couleur d'affichage pour Writeln }
  191.  
  192. {**************************************************************************
  193. *  VG : renvoie une abscisse relative au bord gauche de la fenêtre        *
  194. *       active                                                            *
  195. **-----------------------------------------------------------------------**
  196. *  Entrée : Offset = Distance à partir du bord gauche de la fenêtre       *
  197. *  Sortie : Nombre de colonnes en coordonnées absolues                    *
  198. *  Information    : Si aucune fenêtre n'est ouverte, c'est la totalité de *
  199. *                   l'écran qui sert de cadre de référence                *
  200. *  Variables globales : ViewX1/R                                          *
  201. **************************************************************************}
  202. function VG( Offset : integer ) : byte;
  203.  
  204. begin
  205.   VG:= ViewX1 + Offset;
  206. end;
  207.  
  208.  
  209. {**************************************************************************
  210. *  VD : renvoie une abscisse relative au bord droit de la fenêtre         *
  211. *       active                                                            *
  212. **-----------------------------------------------------------------------**
  213. *  Entrée : Offset = Distance à partir du bord droit de la fenêtre        *
  214. *  Sortie : Nombre de colonnes en coordonnées absolues                    *
  215. *  Information    : Si aucune fenêtre n'est ouverte, c'est la totalité de *
  216. *                   l'écran qui sert de cadre de référence                *
  217. *  Variables globales : ViewX2/R                                          *
  218. **************************************************************************}
  219. function VD( Offset : integer ) : byte;
  220.  
  221. begin
  222.   VD := ViewX2 + Offset;
  223. end;
  224.  
  225. {**************************************************************************
  226. *  VH : renvoie une ordonnée relative au bord supérieur de la fenêtre     *
  227. *       active                                                            *
  228. **-----------------------------------------------------------------------**
  229. *  Entrée : Offset = Distance à partir du bord supérieur de la fenêtre    *
  230. *  Sortie : Nombre de lignes en coordonnées absolues                      *
  231. *  Information    : Si aucune fenêtre n'est ouverte, c'est la totalité de *
  232. *                   l'écran qui sert de cadre de référence                *
  233. *  Variables globales : ViewY1/R                                          *
  234. ***************************************************************************}
  235.  
  236. function VH( Offset : integer ) : byte;
  237.  
  238. begin
  239.   VH := ViewY1 + Offset;
  240. end;
  241.  
  242. {***************************************************************************
  243. *  VB : renvoie une ordonnée relative au bord inférieur de la fenêtre      *
  244. *       active                                                             *
  245. **------------------------------------------------------------------------**
  246. *  Entrée : Offset = Distance à partir du bord inférieur de la fenêtre     *
  247. *  Sortie : Nombre de lignes en coordonnées absolues                       *
  248. *  Information    : Si aucune fenêtre n'est ouverte, c'est la totalité de  *
  249. *                   l'écran qui sert de cadre de référence                 *
  250. *  Variables globales : ViewY2/R                                           *
  251. ***************************************************************************}
  252.  
  253. function VB( Offset : integer ) : byte;
  254.  
  255. begin
  256.   VB := ViewY2 + Offset;
  257. end;
  258.  
  259. {***************************************************************************
  260. *  GetVioPtr : retourne un pointeur sur un caractère donné de la mémoire   *
  261. *              vidéo                                                       *
  262. **------------------------------------------------------------------------**
  263. *  Entrée : Ligne, Colonne = Coordonnées du caractère                      *
  264. *  Sortie : Pointeur sur caractère en mémoire vidéo, de type  VPTR         *
  265. *  Information    : L'origine des coordonnées (0/0) est le coin supérieur  *
  266. *                   gauche de l'écran                                      *
  267. *  Variables globales : VioSeg/R, NbCol/R                                  *
  268. ***************************************************************************}
  269.  
  270. function GetVioPtr( Colonne, Ligne : byte ) : VPTR;
  271.  
  272. begin
  273.   GetVioPtr := Ptr( VioSeg, ( NbCol * Ligne + Colonne ) shl 1);
  274. end;
  275.  
  276. {***************************************************************************
  277. *  WinGetChar : indique le code ASCII d'un caractère se trouvant à un      *
  278. *               emplacement donné                                          *
  279. **------------------------------------------------------------------------**
  280. *  Entrées : Ligne, Colonne = Coordonnées du caractères                    *
  281. *  Sortie : le code ASCII du caractère                                     *
  282. *                                                                          *
  283. *  Variables globales : VioSeg/R, NbCol/R                                  *
  284. ***************************************************************************}
  285.  
  286. function  WinGetChar( Colonne, Ligne : byte ) : char;
  287.  
  288. begin
  289.   WinGetChar := chr(Mem[VioSeg : (NbCol * Ligne + Colonne ) shl 1]);
  290. end;
  291.  
  292. {***************************************************************************
  293. *  WinGetCol : indique la couleur d'un caractère se trouvant à un          *
  294. *              emplacement donné                                           *
  295. **------------------------------------------------------------------------**
  296. *  Entrées : Ligne, Colonne = Coordonnées du caractère                     *
  297. *  Sortie : le code couleur du caractère                                   *
  298. *  Variables globales : VioSeg/R, NbCol/R                                  *
  299. ***************************************************************************}
  300.  
  301. function  WinGetCol( Colonne, Ligne : byte ) : byte;
  302.  
  303. begin
  304.   WinGetCol := Mem[VioSeg : (NbCol * Ligne + Colonne ) shl 1 + 1];
  305. end;
  306.  
  307. {***************************************************************************
  308. *  WinPutChar : écrit un caractère et son attribut directement dans la     *
  309. *               mémoire vidéo                                              *
  310. **------------------------------------------------------------------------**
  311. *  Entrée : Ligne, Colonne = Coordonnées du caractère                      *
  312. *            Caractere     = Caractère à afficher                          *
  313. *            Couleur       = Couleur ou attribut  du caractère             *
  314. *  Information    : l'origine des coordonnées est le point (0,0) situé     *
  315. *                   au coin supérieur gauche de l'écran                    *
  316.                                                                            *
  317. *  Variables globales : VioSeg/R, NbCol/R                                  *
  318. ***************************************************************************}
  319.  
  320. procedure WinPutChar( Colonne, Ligne : byte; Caractere : char; Couleur : byte );
  321.  
  322. var OfsPos : integer; { Offset de la position du caractère en mém. vidéo }
  323.  
  324. begin
  325.   OfsPos := (NbCol * Ligne + Colonne ) shl 1;   { Calcule l'offset }
  326.   Mem[ VioSeg : OfsPos ] := ord( Caractere );  { Ecrit le caractère et   }
  327.   Mem[ VioSeg : OfsPos + 1 ] := Couleur;  { l'attribut en mémoire vidéo }
  328. end;
  329.  
  330. {***************************************************************************
  331. *  WinSetCursor : positionne le curseur clignotant                         *
  332. **------------------------------------------------------------------------**
  333. *  Entrée : Ligne, Colonne = nouvelle position du curseur                  *
  334. *  Variables globales : vLigne/W, vColonne/W                               *
  335. ***************************************************************************}
  336.  
  337. procedure WinSetCursor( Colonne, Ligne : byte );
  338.  
  339. var Regs : Registers;  { Registres utilisés par l'interruption }
  340.  
  341. begin
  342.   Regs.ah := 2;  { Numéro de la fonction Set Cursor }
  343.   Regs.bh := 0;  { Page d'écran concernée }
  344.   Regs.dh := Ligne;  { Transmet la ligne souhaitée }
  345.   vLigne  := Ligne;
  346.   Regs.dl := Colonne;  { Transmet la colonne souhaitée }
  347.   vColonne := Colonne;
  348.   intr($10, Regs);   { Appelle l'interruption du BIOS vidéo }
  349. end;
  350. {***************************************************************************
  351. *  WinDefCursor : définit l'aspect du curseur                              *
  352. **------------------------------------------------------------------------**
  353. *  Entrée : Debut  = Ligne de début du curseur                             *
  354. *           Fin    = Ligne de fin du curseur                               *
  355. *  Variable globale : néant                                                *
  356. ***************************************************************************}
  357.  
  358. procedure WinDefCursor( Debut, Fin : byte );
  359.  
  360. var Regs : Registers;   { Registres utilisés par l'interruption }
  361.  
  362. begin
  363.   Regs.ah := 1;   { Numéro de la fonction }
  364.   Regs.ch := Debut;  { Charge les lignes de début et de fin }
  365.   Regs.cl := Fin;
  366.   intr($10, Regs);  { Déclenche l'interruption du BIOS vidéo }
  367. end;
  368.  
  369. {***************************************************************************
  370. *  WinHideCursor : retire le curseur de l'écran                            *
  371. **------------------------------------------------------------------------**
  372. *  Entrée : néant                                                          *
  373. *  Variable globale : NbLig/R                                              *
  374. ***************************************************************************}
  375.  
  376. procedure WinHideCursor;
  377.  
  378. begin
  379.   WinSetCursor( 0, NbLig + 1 );  {Place le curseur en dehors de l'écran }
  380. end;
  381.  
  382. {***************************************************************************
  383. *  WinBlockCursor : définit le curseur comme un rectangle recouvrant       *
  384. *                   le caractère situé en-dessous                          *
  385. **------------------------------------------------------------------------**
  386. *  Entrée : néant                                                          *
  387. *  Variable globale : Color/R                                              *
  388. ***************************************************************************}
  389.  
  390. procedure WinBlockCursor;
  391.  
  392. begin
  393.   if ( Color ) then    { Carte couleur ? }
  394.     WinDefCursor( 0, 7 )  { Oui }
  395.   else     { Carte monochrome }
  396.     WinDefCursor( 0, 13 );
  397. end;
  398.  
  399. {***************************************************************************
  400. *  WinLineCursor : définit le curseur comme un tiret s'étendant            *
  401. *                  sur les deux dernières lignes de trame                  *
  402. **------------------------------------------------------------------------**
  403. *  Entrée : néant                                                          *
  404. *  Variable globale : Color/R                                              *
  405. ***************************************************************************}
  406.  
  407. procedure WinLineCursor;
  408.  
  409. begin
  410.   if ( Color ) then  { Carte couleur ? }
  411.     WinDefCursor( 6, 7 )      { Oui }
  412.  else   { Carte monochrome }
  413.     WinDefCursor( 12, 13 );
  414. end;
  415.  
  416. {***************************************************************************
  417. *  WinSetView : définit une zone de l'écran comme zone de visualisation    *
  418. *               à laquelle se réfèrent les fonctions VG, VD, VH, VB        *
  419. **------------------------------------------------------------------------**
  420. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche de la zone      *
  421.   x2, y2 = Coordonnées du coin inférieur droit de la zone                  *
  422. *  Variables globales : ViewX1/W, ViewX2/W, ViewY1/W, ViewY2/W             *
  423. ***************************************************************************}
  424.  
  425. procedure WinSetView( x1, y1, x2, y2 : byte);
  426.  
  427. begin
  428.   ViewX1 := x1;    { Mémorise les coordonnées dans }
  429.   ViewY1 := y1;    { les variables globales }
  430.   ViewX2 := x2;
  431.   ViewY2 := y2;
  432. end;
  433.  
  434. {***************************************************************************
  435. *  WinGetView : indique la zone de visualisation actuelle                  *
  436. *                                                                          *
  437. **------------------------------------------------------------------------**
  438. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche de la zone      *
  439. *            x2, y2 = Coordonnées du coin inférieur droit de la zone       *
  440. *  Information    : la zone de visualisation sert de cadre de référence    *
  441. *                   aux fonctions VG, VD, VH, VB                           *
  442. *  Variables globales : ViewX1/R, ViewX2/R, ViewY1/R, ViewY2/R             *
  443. ***************************************************************************}
  444.  
  445. procedure WinGetView( var x1, y1, x2, y2 : byte );
  446.  
  447. begin
  448.   x1 := ViewX1;   { Prend les coordonnées dans   }
  449.   y1 := ViewY1;   { les variables globales       }
  450.   x2 := ViewX2;
  451.   y2 := ViewY2;
  452. end;
  453.  
  454. {***************************************************************************
  455. *  WinWrite2View: active ou désactive la prise en compte par Writeln       *
  456. *                 de la zone de visualisation actuelle                     *
  457. **------------------------------------------------------------------------**
  458. *  Entrées : Doit = TRUE : fait respecter la zone de visualisation         *
  459. *                   FALSE: désigne l'écran dans sa totalité comme          *
  460. *                          référence d'affichage.                          *
  461. *                          Pas de défilement en fin d'écran                *
  462. *  Globals : Write2View/W                                                  *
  463. ***************************************************************************}
  464.  
  465. procedure WinWrite2View( Doit : boolean );
  466.  
  467. begin
  468.   Write2View := Doit; { Mémorise un indicateur }
  469. end;
  470.  
  471.  
  472. {**************************************************************************
  473. *  WhereX : retourne la colonne d'affichage de la prochaine instruction   *
  474. *           Writeln appliquée à la variable fichier OUTPUT                *
  475. **-----------------------------------------------------------------------**
  476. *  Entrée : néant                                                         *
  477. *  Sortie : cf supra                                                      *
  478. *  Variables globales : WritelnX/R                                        *
  479. **************************************************************************}
  480.  
  481. function WhereX : integer;
  482.  
  483. begin
  484.   WhereX := WritelnX;  { Retourne la colonne d'affichage }
  485. end;
  486.  
  487. {***************************************************************************
  488. *  WhereY : retourne la ligne d'affichage de la prochaine instruction      *
  489. *           Writeln appliquée à la variable fichier OUTPUT                 *
  490. **------------------------------------------------------------------------**
  491. *  Entrée : néant                                                          *
  492. *  Sortie : cf supra                                                       *
  493. *  Variables globales : WritelnY/R                                         *
  494. ***************************************************************************}
  495.  
  496. function WhereY : integer;
  497.  
  498. begin
  499.   WhereY := WritelnY;   { Retourne la ligne d'affichage }
  500. end;
  501.  
  502. {**************************************************************************
  503. *  TextColor : fixe la couleur des caractères pour l'affichage            *
  504. *              par Writeln                                                *
  505. **-----------------------------------------------------------------------**
  506. *  Entrée : Col = la couleur de caractère choisie (0-15)                  *
  507. *  Variables globales : WritelnCol/RW                                     *
  508. **************************************************************************}
  509.  
  510. procedure TextColor( Color : byte );
  511.  
  512. begin
  513.   WritelnCol := ( WritelnCol and $F0 ) or Color;  { Met la couleur }
  514. end;
  515.  
  516. {***************************************************************************
  517. *  TextBackground : fixe la couleur de fond pour l'affichage               *
  518. *                   par Writeln .                                          *
  519. **------------------------------------------------------------------------**
  520. *  Entrée : Col = la couleur de fond choisie (0-15)                        *
  521. *  Variables globales : WritelnCol/RW                                      *
  522. ***************************************************************************}
  523.  
  524. procedure TextBackground( Color : byte );
  525.  
  526. begin
  527.   WritelnCol := ( WritelnCol and $0F ) or ( Color shl 4 );  { Met la couleur }
  528. end;
  529.  
  530. {***************************************************************************
  531. *  ClrScr : efface l'écran                                                 *
  532. **------------------------------------------------------------------------**
  533. *  Entrée : néant                                                          *
  534. *  Information    : Remplace la procédure homonyme de l'unité Crt          *
  535. *  Variables globales : NbCol/R, NbLig/R, WritelnCol/R                     *
  536. ***************************************************************************}
  537.  
  538. procedure ClrScr;
  539.  
  540. begin
  541.   WinFill( 0, 0, NbCol-1, NbLig-1, ' ', WritelnCol );
  542. end;
  543.  
  544. {**************************************************************************
  545. *  GotoXY : remplace la procédure GotoXY de l'unité CRT                   *
  546. *           fixe la position d'affichage pour le prochain appel           *
  547. *           de la procédure Writeln détournée                             *
  548. **-----------------------------------------------------------------------**
  549. *  Entrées : X = Colonne d'affichage                                      *
  550. *            Y = Ligne d'affichage                                        *
  551. *  Information    : le curseur visible n'est pas affecté                  *
  552. *  Variables globales : WritelnX/W, WritelnY/W, WritelnPtr/W              *
  553. **************************************************************************}
  554.  
  555. procedure GotoXY( X, Y : integer );
  556.  
  557. begin
  558.   WritelnX := X;   { Mémorise la position dans la variable globale }
  559.   WritelnY := Y;
  560.   WritelnPtr := GetVioPtr( x, y ); { Pointe sur la nouvelle position }
  561. end;
  562.  
  563. {***************************************************************************
  564. *  GetScr : mémorise dans un buffer une zone de l'écran                    *
  565. **------------------------------------------------------------------------**
  566. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche de la zone      *
  567. *            x2, y2 = Coordonnées du coin inférieur droit de la zone       *
  568. *            BufPtr = Pointe sur le buffer destiné à stocker la zone       *
  569. *  Information    : Le buffer contient les lignes sous forme linéaire      *
  570. *                   juxtaposée                                             *
  571. *  Variables globales : néant                                              *
  572. ***************************************************************************}
  573.  
  574. procedure GetScr( x1, y1, x2, y2 : byte; BufPtr : pointer );
  575.  
  576. var nbytes : integer;  { Nombre d'octets à copier par ligne }
  577.  
  578. begin
  579.   nbytes := ( x2 - x1 + 1 ) shl 1;   { Octets par ligne }
  580.   while y1 <= y2 do   { Parcourt les lignes }
  581.     begin
  582.       Move( GetVioPtr(x1, y1)^, BufPtr^, nbytes);
  583.       inc( PTRREC( BufPtr ).Ofs, nbytes );
  584.       inc( y1 );     { Y1 = ligne suivante }
  585.     end;
  586. end;
  587.  
  588. {****************************************************************************
  589. *  PutScr : copie directement le contenu d'un buffer dans la mémoire vidéo  *
  590. **-------------------------------------------------------------------------**
  591. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche de la zone       *
  592. *            x2, y2 = Coordonnées du coin inférieur droit de la zone        *
  593. *            BufPtr = Pointe sur le buffer à recopier dans la mémoire vidéo *
  594. *  Information    : Le buffer doit être au format défini par PutScr         *
  595. *  Variables globales : néant                                               *
  596. ****************************************************************************}
  597.  
  598. procedure PutScr( x1, y1, x2, y2 : byte; BufPtr : pointer );
  599.  
  600. var nbytes : integer;  { Nombre d'octets à copier par ligne }
  601.  
  602. begin
  603.   nbytes := ( x2 - x1 + 1 ) shl 1;  { Octets par ligne }
  604.   while y1 <= y2 do   { Parcourt les lignes }
  605.     begin
  606.       Move( BufPtr^, GetVioPtr(x1, y1)^, nbytes);
  607.       inc( PTRREC( BufPtr ).Ofs, nbytes );
  608.       inc( y1 );        { Y1 = ligne suivante }
  609.     end;
  610. end;
  611.  
  612. {***************************************************************************
  613. *  WinOpen : ouvre une fenêtre                                             *
  614. **------------------------------------------------------------------------**
  615. *  Entrées : x1, y1 = Coordonnées du coin supérieur gauche                 *
  616. *            x2, y2 = Coordonnées du coin inférieur droit                  *
  617. *  Sortie : Numéro (handle) permettant d'accéder par la suite              *
  618. *            la fenêtre                                                    *
  619. *  Information    : Si la fenêtre n'a pas pu être ouverte en raison du     *
  620. *                   manque de mémoire sur le tas, le numéro retourné a     *
  621. *                   la valeur WinOpenError (-1)                            *
  622. *  Variables globales : vLigne/R, vColonne/R, ViewX1/R, ViewX2/R,          *
  623. *                       ViewY1/R, ViewY2/R, NbWin/W, FirstWinPtr/RW,       *
  624. *                       ActWInPtr/RW, HaPtr^/RW                            *
  625. ***************************************************************************}
  626.  
  627. function WinOpen( x1, y1, x2, y2 : byte ) : integer;
  628.  
  629. var i, j,    { Compteurs d'itérations }
  630.     Key,     { Mémorise le numéro d'accès }
  631.     BufLen : integer;  { Taille du buffer }
  632.     WinPtr : WIPTR;    { Decsripteur de fenêtre }
  633. begin
  634.   BufLen := ( x2 - x1 + 1 ) * ( y2 - y1 + 1 ) shl 1;
  635.   if MaxAvail >= BufLen + SizeOf( WINDES ) - 1 then
  636.     begin   { Il reste assez de mémoire }
  637.       GetMem( WinPtr, BufLen + SizeOf( WINDES ) - 1 );
  638.       WinPtr^.x1      := x1;    { Transfère les coordonnées }
  639.       WinPtr^.x2      := x2;    { de la fenêtre }
  640.       WinPtr^.y1      := y1;    { dans le descripteur }
  641.       WinPtr^.y2      := y2;
  642.       WinPtr^.curc    := vColonne;  { Mémorise également la position }                     
  643.                                      { actuelle du curseur }
  644.       WinPtr^.curl    := vLigne; 
  645.       WinPtr^.ViewX1  := ViewX1; { Transfère les coordonnées }
  646.       WinPtr^.ViewY1  := ViewY1; { de la zone de visualisation }
  647.       WinPtr^.ViewX2  := ViewX2; { dans le descripteur }
  648.       WinPtr^.ViewY2  := ViewY2; 
  649.       WinPtr^.Attribut:= 0;      { Pas encore d'attribut }
  650.       WinPtr^.LastWin := ActWinPtr;  { Lien avec la fenêtre précédente }
  651.       WinPtr^.NextWin := NIL;    { Pas encore de successeur }
  652.  
  653.       GetScr( x1, y1, x2, y2, @WinPtr^.Buffer );
  654.       ActBufPtr := VELARPTR(@WinPtr^.Buffer);  { Pointe sur le buffer }
  655.  
  656.       WinSetView( x1, y1, x2, y2 ); { Zone de visualisation = la fenêtre }
  657.  
  658.       if ActWinPtr <> NIL then  { Existait-il déjà une autre fenêtre ? }
  659.         ActWinPtr^.NextWin := WinPtr {Oui, la relie à la nouvelle }
  660.       else  { Non la présente est la première et la seule fenêtre  }
  661.         FirstWinPtr := WinPtr; { Pointe sur la première fenêtre }
  662.       ActWinPtr := WinPtr; { Pointe sur la fenêtre active }
  663.  
  664.       inc( NbWin );  { Incrémente le nombre de fenêtres ouvertes }
  665.  
  666.       {-- Recherche un numéro libre pointé par HaPtr ---------}
  667.  
  668.       Key := 0;   { numéro = rang du bit }
  669.       while (HaPtr^[ Key shr 3 ] and ( 1 shl (Key and 7) )) <> 0 do
  670.         inc( Key );  { Numéro déjà attribué, passe au suivant }
  671.       HaPtr^[ Key shr 3 ] := HaPtr^[ Key shr 3 ] or ( 1 shl ( Key and 7 ));
  672.       WinPtr^.Handle := Key;   { Mémorise le numéro dans le descripteur }
  673.       WinOpen := Key;   { Passe le numéro au programme appelant }
  674.     end
  675.   else  { Pas assez de mémoire pour le descripteur et le buffer associé }
  676.     WinOpen := -1;
  677. end;
  678.  
  679. {***************************************************************************
  680. *  WinClose : referme la dernière fenêtre ouverte                          *
  681. **------------------------------------------------------------------------**
  682. *  Entrée : Redraw = TRUE : le contenu de l'écran recouvert par la         *
  683. *                            fenêtre est restauré                          *
  684. *  Information    : Le programme appelant doit s'assurer qu'au moment de   *
  685. *                   l'appel de la procédure il reste au moins une fenêtre  *
  686. *                   ouverte                                                *
  687. *  Variables globales : ActWinPtr/RW, FirstWinPtr/RW, HaPTr^/RW, NbWin/W   *
  688. ***************************************************************************}
  689.  
  690. procedure WinClose( ReDraw : boolean );
  691.  
  692. var WinPtr : WIPTR;  { Pointe sur le descripteur actuel }
  693.  
  694. begin
  695.   with ActWinPtr^ do
  696.     begin
  697.       {-- Restitue le numéro de la fenêtre --------------------}
  698.  
  699.       HaPtr^[ Handle shr 3 ] := HaPtr^[ Handle shr 3 ] and
  700.                                                not( 1 shl ( Handle and 7 ));
  701.  
  702.       if ReDraw then   { Faut-il reconstituer l'écran ? }
  703.         PutScr( x1, y1, x2, y2, @Buffer ); { Oui  }
  704.       WinSetView( ViewX1, ViewY1, ViewX2, ViewY2 );  { ancienne zone de visualisation }
  705.       WinSetCursor( curc, curl ); { Ramène le cusreur à son ancienne position }
  706.       WinPtr := ActWinPtr;  { Mémorise le pointeur sur le descript. actuel }
  707.       ActWinPtr := LastWin;  { Pointe sur le descripteur précédent }
  708.       if LastWin <> NIL then   { Plus de fenêtre ouverte ? }
  709.         ActWinPtr^.NextWin := NIL  { Oui, plus de successeur }
  710.       else   { Non }
  711.         FirstWinPtr := NIL;  { Ne pointe sur rien }
  712.  
  713.       {-- Libère la mémoire allouée pour le descripteur ---}
  714.       FreeMem( WinPtr, (x2-x1+1) * (y2-y1+1) shl 1 + SizeOf(WINDES) - 1);
  715.  
  716.       ActBufPtr := VELARPTR(@ActWinPtr^.Buffer); { Pointe sur le buffer }
  717.  
  718.       dec( NbWin );  { Décrémente le nombre de fenêtres ouvertes }
  719.     end;
  720. end;
  721.  
  722. {***************************************************************************
  723. *  WinStRep : construit une chaîne de caractères répétitifs                *
  724. **------------------------------------------------------------------------**
  725. *  Entrée : Caractere = le caractère à répéter                             *
  726. *              Nombre = Nombre de répétitions ou longueur de la chaîne     *
  727. *  Sortie : la chaîne construite                                           *
  728. *  Variable globale : néant                                                *
  729. ***************************************************************************}
  730.  
  731. function WinStRep( Caractere : char; Nombre : byte ) : string;
  732.  
  733. var StrepString : String;   { Pour contenir la chaîne }
  734.  
  735. begin
  736.   StrepString[0] := chr( Nombre );
  737.   FillChar( StrepString[1], Nombre, Caractere );
  738.   WinStRep := StrepString;
  739. end;
  740.  
  741. {***************************************************************************
  742. *  WinPrint : écrit une chaîne directement dans la mémoire vidéo           *
  743. **------------------------------------------------------------------------**
  744. *  Entrées : Colonne, Ligne = Position d'affichage                         *
  745. *            Couleur         = Couleur ou attribut du caractère à afficher *
  746. *            Sortie          = Chaîne à afficher                           *
  747. *  Information : - Si la chaîne dépasse la fin de la ligne, l'affichage se *
  748. *                  poursuit à la ligne suivante                            *
  749. *                - Si la fin de l'écran ou de la fenêtre active est        *
  750. *                  atteinte, il n'y a pas de défilement vers le haut       *
  751. *  Variable globale : néant                                                *
  752. ***************************************************************************}
  753.  
  754. procedure WinPrint( Colonne, Ligne, Couleur : byte; Sortie : string );
  755.  
  756. var VioPtr : VPTR;     { Pointe sur la mémoire vidéo }
  757.     i, j   : byte;     { Compteurs d'itérations }
  758.  
  759. begin
  760.   VioPtr := GetVioPtr( Colonne, Ligne ); { Charge un pointeur }
  761.   j := length( Sortie ); { Détermine la longueur de la chaîne }
  762.   for i:=1 to j do   { Parcourt les caractères de la chaîne }
  763.     begin
  764.       VioPtr^.Caractere := ord( Sortie[i] ); { Met le caractère et }
  765.       VioPtr^.Attribut := Couleur;  { son attribut dans la mémoire vidéo }
  766.       inc( PTRREC( VioPtr ).Ofs, 2 ); { Passe au caractère suivant }
  767.     end;
  768. end;
  769.  
  770. {***************************************************************************
  771. *  WinFill : remplit une zone de l'écran avec un caractère et une          *
  772. *            couleur donnés                                                *
  773. **------------------------------------------------------------------------**
  774. *  Entrées: x1, y1  = Coordonnées du coin supérieur gauche de la zone      *
  775. *            x2, y2 = Coordonnées du coin inférieur droit de la zone       *
  776. *            Caractere,                                                    *
  777. *            Couleur   = le caractère et son attribut                      *
  778. *  Variable globale : néant                                                *
  779. ***************************************************************************}
  780. procedure WinFill( x1, y1, x2, y2 : byte; Caractere : char; Couleur : byte );
  781.  
  782. var Ligne : string;  { Mémorise une ligne de caractères }
  783.  
  784. begin
  785.   Ligne := WinStRep( Caractere, x2-x1+1 );    { Fabrique une ligne }
  786.   while y1 <= y2 do      { Parcourt la zone ligne par ligne }
  787.     begin
  788.       WinPrint( x1, y1, Couleur, Ligne );  { Affiche la ligne fabriquée }
  789.       inc( y1 );   { Passe à la ligne suivante }
  790.     end;
  791. end;
  792.  
  793. {***************************************************************************
  794. *  WinFrame : trace un cadre autour d'une zone de l'écran                  *
  795. **------------------------------------------------------------------------**
  796. *  Entrées : x1, y1  = Coordonnées du coin supérieur gauche de la zone     *
  797. *            x2, y2  = Coordonnées du coin inférieur droit de la zone      *
  798. *            Cadre   = l'une des constantes CAD_SIM, CAD_DOU, etc          *
  799. *            Couleur = Couleur (attribut) du cadre                         *
  800. *  Variable globale : néant                                                *
  801. ***************************************************************************}
  802.  
  803. procedure WinFrame( x1, y1, x2, y2, Cadre, Couleur : byte );
  804.  
  805. type CadStruc = record   { Liste des caractères formant le cadre }
  806.                 SupGauche,
  807.                 SupDroite,
  808.                 InfGauche,
  809.                 InfDroite,
  810.                 Vertical,
  811.                 Horizontal  : char;
  812.               end;
  813.  
  814. const CadCaractere : array[1..4] of CadStruc =  { Types de cadres disponibles }
  815.        (
  816.         ( SupGauche   : '┌'; SupDroite  : '┐'; InfGauche  : '└';
  817.           InfDroite : '┘'; Vertical    : '│'; Horizontal  : '─' ),
  818.         ( SupGauche   : '╔'; SupDroite  : '╗'; InfGauche  : '╚';
  819.           InfDroite : '╝'; Vertical    : '║'; Horizontal  : '═' ),
  820.         ( SupGauche   : '▒'; SupDroite  : '▒'; InfGauche  : '▒';
  821.           InfDroite : '▒'; Vertical    : '▒'; Horizontal  : '▒' ),
  822.         ( SupGauche   : '█'; SupDroite  : '█'; InfGauche  : '█';
  823.           InfDroite : '█'; Vertical    : '█'; Horizontal  : '█' )
  824.        );
  825.  
  826. var StrepBuf : string;  { Stocke une ligne horizontale }
  827.     Ligne    : byte;   { Compteur }
  828.  
  829. begin
  830.  with CadCaractere[ Cadre ] do
  831.    begin
  832.      WinPutChar( x1, y1, SupGauche, Couleur );  { Dessine les quatre }
  833.      WinPutChar( x2, y1, SupDroite, Couleur );  { coins du cadre }
  834.      WinPutChar( x1, y2, InfGauche, Couleur );
  835.      WinPutChar( x2, y2, InfDroite, Couleur );
  836.  
  837.      StrepBuf := WinStRep( Horizontal, x2-x1-1 );  { puis les deux lignes }
  838.      WinPrint( x1+1, y1, Couleur, StrepBuf );      { horizontales }
  839.      WinPrint( x1+1, y2, Couleur, StrepBuf );           
  840.  
  841.      dec( y2 );   { Fixe la fin de la boucle qui suit }
  842.      for Ligne:=y1+1 to y2 do  { Parcourt les lignes }
  843.        begin                   { et trace les verticales  }
  844.          WinPutChar( x1, Ligne, Vertical, Couleur );
  845.          WinPutChar( x2, Ligne, Vertical, Couleur );
  846.        end;
  847.    end;
  848. end;
  849.  
  850. {***************************************************************************
  851. *  WinColor : remplit une zone de l'écran avec un attribut donné           *
  852. *             sans modifier les caractères de la zone                      *
  853. **------------------------------------------------------------------------**
  854. *  Entrées : x1, y1  = Coordonnées du coin supérieur gauche de la zone     *
  855. *            x2, y2  = Coordonnées du coin inférieur droit de la zone      *
  856. *            Couleur = la nouvelle couleur des caractères                  *
  857. *  Variable globale : LigneOfs/R                                           *
  858. ***************************************************************************}
  859.  
  860. procedure WinColor( x1, y1, x2, y2, Couleur : byte );
  861.  
  862. var VioPtr : VPTR;   { Pointe sur la mémoire vidéo }
  863.     Ligne,    { Compteur de lignes }
  864.     Colonne,  { Compteur de colonnes }
  865.     DeltaX : integer; { Différence entre deux lignes  }
  866.  
  867. begin
  868.   VioPtr := GetVioPtr( x1, y1 ); { Pointe sur le premier caractère }
  869.   DeltaX := LigneOfs - ( (x2-x1) shl 1 ) - 2;  { Offset de x2 à x1 }
  870.  
  871.   for Ligne:=y1 to y2 do   { Parcourt les lignes }
  872.     begin    { Parcourt les colonnes }
  873.       for Colonne:=x1 to x2 do
  874.         begin
  875.           VioPtr^.Attribut := Couleur;  { Enregistre la couleur  }
  876.           inc( PTRREC(VioPtr).Ofs, 2 ); { Augmente l'offset de 2 }
  877.         end;
  878.       inc( PTRREC(VioPtr).Ofs, DeltaX );
  879.     end;
  880. end;
  881.  
  882. {***************************************************************************
  883. *  WinShadow : dessine une ombre                                           *
  884. **------------------------------------------------------------------------**
  885. *  Entrées : x1, y1  = Coordonnées du coin supérieur gauche de l'ombre     *
  886. *            x2, y2  = Coordonnées du coin infériur droit de l'ombre       *
  887. *            BufPtr  = Pointeur désignant le buffer à manipuler            *
  888. *                      Information. En mode couleur, l'ombre est générée   *
  889. *                      par modification des attributs des caractères,      *
  890. *                      tandis qu'en mode monochrome, les caractères        *
  891. *                      recouverts par l'ombre sont remplacés par  '▒'      *
  892. *  Variables globales : NbCol/R, Color/R, LigneOfs/R                       *
  893. ***************************************************************************}
  894.  
  895. procedure WinShadow( x1, y1, x2, y2 : byte; BufPtr : VPTR );
  896.  
  897. var Attribut : byte;   { Attribut à manipuler }
  898.     Ligne,             { Compteur de lignes }
  899.     Colonne,           { Compteur de colonnes }
  900.     DeltaX   : integer;  { Distance à parcourir sur une ligne }
  901.  
  902. begin
  903.   inc( PTRREC( BufPtr ).Ofs, ( y1 * NbCol + x1 ) shl 1 );  { Charge le pointeur }
  904.   DeltaX := LigneOfs - ( (x2-x1) shl 1 ) - 2;  { Offset de x2 à x1 }
  905.  
  906.   if ( Color ) then   { Mode couleur ? }
  907.     for Ligne := y1 to y2 do   { Parcourt les lignes }
  908.       begin   { Parcourt les caractères d'une ligne }
  909.         for Colonne := x1 to x2 do
  910.           begin
  911.             Attribut := BufPtr^.Attribut;  { Attribut du caractère }
  912.  
  913.             {-- Change la couleur de fond ----------------------------}
  914.  
  915.             if Attribut and 128 <> 0 then { Fond clair ? }
  916.               Attribut := Attribut and 128  { Oui, modifie le bit 7 }
  917.             else   { Non, fond normal }
  918.               Attribut := Attribut and 15;  { Met un fond sombre }
  919.  
  920.             {-- Change la couleur du caractère ------------------------}
  921.  
  922.             if Attribut and 8 <> 0 then  { Caractère clair ? }
  923.               Attribut := Attribut and (255 - 8); { Oui, modifie le bit 3 }
  924.               BufPtr^.Attribut := Attribut;  { Remet l'attribut dans la mémoire vidéo }
  925.             inc( PTRREC(BufPtr).Ofs, 2 );  { Pointe sur le caractère suivant }
  926.           end;
  927.         inc( PTRREC(BufPtr).Ofs, DeltaX );  { Pointe sur la ligne suivante}
  928.       end
  929.   else   { Non, mode monochrome }
  930.     for Ligne := y1 to y2 do   { Parcourt les lignes }
  931.       begin    { Parcourt les caractères d'une ligne }
  932.         for Colonne := x1 to x2 do
  933.           begin
  934.             BufPtr^.Contenu := ord( '▒' ) + ( $7 shl 8 );  { Fixe l'attribut }
  935.             inc( PTRREC(BufPtr).Ofs, 2 );  { Passe au caractère suivant }
  936.           end;
  937.         inc( PTRREC(BufPtr).Ofs, DeltaX ); { Passe à la ligne suivante }
  938.       end
  939. end;
  940.  
  941. {***************************************************************************
  942. *  WinOpenShadow : ouvre une nouvelle fenêtre et dessine son ombre         *
  943. **------------------------------------------------------------------------**
  944. *  Entrées: x1, y1  = Coordonnées du coins supérieur gauche                *
  945. *           x2, y2  = Coordonnées du coin inférieur droit                  *
  946. *  Information    : - la largeur et la profondeur de l'ombre sont fixées   *
  947. *                     par les variables globales ShadowX et ShadowY        *
  948. *                   - les coordonnées transmises ne doivent pas inclure    *
  949. *                     l'ombre et doivent être choisies de telle sorte qu'il*
  950. *                     reste de la place pour dessiner l'ombre sur l'écran  *
  951. *                   - en mode couleur, l'ombre est générée par modification*
  952. *                     des attributs des caractères, tandis qu'en mode      *
  953. *                     monochrome, les caractères recouverts par l'ombre    *
  954. *                     sont remplacés par  '▒'                              *
  955. *  Variables globales : ActWinPTr^/W                                       *
  956. ***************************************************************************}
  957.  
  958. function WinOpenShadow( x1, y1, x2, y2 : byte ) : integer;
  959.  
  960. var  Handle : integer;   { Numéro de la fenêtre ouverte }
  961.  
  962. begin
  963.   Handle := WinOpen( x1, y1, x2 + ShadowX, y2 + ShadowY);
  964.   if ( Handle <> WinOpenError ) then
  965.     begin
  966.       ActWinPtr^.Attribut := WIN_OMBRE; { La fenêtre a une ombre }
  967.       WinSetView( x1, y1, x2, y2 ); { L'ombre est en dehors de la zone de visualisation }
  968.       WinShadow( x2+1, y1+1, x2+ShadowX, y2+ShadowY, VPTR(ptr(VioSeg,0)) );
  969.       WinShadow( x1+ShadowX, y2+1, x2, y2+ShadowY, VPTR(ptr(VioSeg,0)) );
  970.     end;
  971.   WinOpenShadow := Handle; { Renvoie le numéro de la fenêtre }
  972. end;
  973.  
  974. {$I win2.pas}
  975. {***************************************************************************
  976. *  WinInit : Initialise l'unité Win.                                       *
  977. *  Variables globales : VioCarte/W, NbCol/W, NbLig/W, Color/W, VioSeg/W,   *
  978. *                       HaPtr/W, LigneOfs/W                                *
  979. ***************************************************************************}
  980.  
  981. procedure WinInit;
  982.  
  983. const VioMode : array [0..11] of byte = ( MDA, CGA, 0, EGA, EGA_MONO, 0,
  984.                                           VGA_MONO,  VGA, 0, MCGA,
  985.                                           MCGA_MONO, MCGA );
  986.  
  987.       EgaMode : array [0..2] of byte  = ( EGA, EGA, EGA_MONO );
  988.  
  989. var Regs : Registers;   { Registres du processeur pour les interruptions }
  990.  
  991. begin
  992.   VioCarte := $ff;    { Pas encore de carte vidéo détectée }
  993.  
  994.   {-- teste s'il y a une carte VGA ou MCGA ---------------------}
  995.  
  996.   Regs.ax := $1a00;  { Invoque la fonction 1Ah du BIOS vidéo }
  997.   intr($10, Regs);   
  998.   if Regs.al = $1a then    { VGA ou MCGA? }
  999.     begin                  { Oui }
  1000.       VioCarte := VioMode[ Regs.bl-1 ];  { Cherche le code dans la table }
  1001.       Color := not( ( VioCarte = MDA ) or ( VioCarte = EGA_MONO ) );
  1002.     end
  1003.   else    { Ni VGA ni MCGA }
  1004.     begin    { Est-ce de l'EGA ?  }
  1005.       Regs.ah := $12;  { Appelle la fonction 12h avec BL=10h }
  1006.       Regs.bl := $10;   
  1007.       intr($10, Regs);  { dans le BIOS vidéo }
  1008.       if Regs.bl <> $10 then  { EGA ? }
  1009.         begin                 { Oui }
  1010.           VioCarte := EgaMode[ (Regs.cl shr 1) div 3 ]; { Cherche le code }
  1011.           Color := VioCarte <> EGA_MONO;
  1012.         end;
  1013.     end;
  1014.  
  1015.   {-- Fixe le pointeur sur la mémoire vidéo -----------------------------}
  1016.  
  1017.   Regs.ah := 15;    { Recherche le mode vidéo actuel }
  1018.   intr($10, Regs);  { en apelant une interrution du BIOS vidéo  }
  1019.   if Regs.al = 7 then   { Mode monochrome ? }
  1020.     VioSeg := $b000   { Oui, début de mémoire vidéo en B000 }
  1021.   else                { Non, mode couleur }
  1022.     VioSeg := $b800;  { Début de mémoire vidéo en B800 }
  1023.  
  1024.   if VioCarte = $ff then   { ni EGA, ni VGA ni MCGA }
  1025.     begin     { Oui }
  1026.       if Regs.al = 7 then VioCarte := MDA
  1027.                      else VioCarte := CGA;
  1028.       NbLig := 25;     { Mode 25 lignes }
  1029.       Color := not( ( Regs.al=0 ) or ( Regs.al=2 ) or ( Regs.al=7 ) );
  1030.     end
  1031.   else     { = EGA, VGA ou MCGA, lit le nombre de lignes ...}
  1032.    NbLig := BPTR( Ptr( $40, $84 ) )^ + 1;
  1033.  
  1034.   NbCol := BPTR( Ptr( $40, $4a ) )^;  {... et de colonnes }
  1035.   LigneOfs := NbCol shl 1;  { Déplacement jusqu'au début de la }
  1036.                             { ligne suivante } 
  1037.  
  1038.   Regs.ah := 5;    { Sélectionne la page d'écran active }
  1039.   Regs.al := 0;    { Page 0 }
  1040.   intr($10, Regs); { par l'interruption du BIOS vidéo }
  1041.  
  1042.   Regs.ah := 3;    { Lit la position actuelle du curseur }
  1043.   Regs.bh := 0;    { en page 0 }
  1044.   intr($10, Regs); { par l'interruption du BIOS vidéo }
  1045.   vLigne  := Regs.dh;   { Mémorise la position du curseur }
  1046.   vColonne := Regs.dl;
  1047.   WinSetView(0, 0, NbCol-1, NbLig-1);  { Zone de visualisation = }
  1048.                                        { la totalité de l'écran }
  1049.   New( HaPtr );   { Réserve de la place pour le tableau des numéros }
  1050.   FillChar( HaPtr^, SizeOf( HaPtr^ ), 0 ); { Initialise le tableau }
  1051.  
  1052.   {-- Dirige la variable fichier  OUTPUT vers des routines de sortie         internes -----------}
  1053.  
  1054.   with TextRec( Output ) do   { Manipule la variable OUTPUT }
  1055.     begin
  1056.       Handle   := $FFFF;    { Valeur attendue par Turbo Pascal 
  1057.       Mode     := fmClosed; { Périphérique ferné }
  1058.       BufSize  := SizeOf( Buffer ); { Fixe la taille et l'adresse  }
  1059.       BufPtr   := @Buffer;           { du buffer  }
  1060.       OpenFunc := @OutputOpen;  { Adresse de la procédure Open }
  1061.       Name[0]  := #0;           { Pas de nom pour le moment }
  1062.     end;
  1063.   Rewrite( Output );    { Initialise la variable fichier }
  1064.  
  1065.   {-- Affichage par Writeln à partir de la position actuelle du curseur --}
  1066.   {   en page 0 }
  1067.   WritelnX := vColonne;
  1068.   WritelnY := vLigne;
  1069.   WritelnPtr := GetVioPtr( vColonne, vLigne );
  1070.  
  1071. end;
  1072. {**--------------------------------------------------------------------**}
  1073. {** Ici commence le code de l'unité                                    **}
  1074. {**--------------------------------------------------------------------**}
  1075.  
  1076. begin
  1077.   WinInit;       { Invoque la procédure d'initialisation }
  1078. end.
  1079.  
  1080.  
  1081.  
  1082.