Advertisement
Swiftkill

TPU Screen

Oct 2nd, 2019
254
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pascal 10.01 KB | None | 0 0
  1. {***************************************************************************}
  2. {*                                                                         *}
  3. {*   Модуль поддержки работы с окнами (расширенный CRT) версия 4           *}
  4. {*   Для большой программы                                                 *}
  5. {*   Написано Я.Н.Стерховым.    Язык Турбо-Паскаль 5.0/7.0                 *}
  6. {*                                                                         *}
  7. {***************************************************************************}
  8. {$F+,O+,N+,E+,D+}
  9. UNIT Screen;
  10. INTERFACE
  11. USES CRT,DOS;
  12.  
  13. TYPE
  14.   {Структура символа с атрибутом}
  15.   ChAttr = RECORD
  16.              ASCII :Char;
  17.              Attr  :Byte;
  18.   END;
  19.  
  20.   {Массив цветных символов - максимальный размер: весь экран }
  21.   Image = RECORD
  22.            Chars       :PACKED ARRAY[1..80,1..25] OF ChAttr;
  23.            Heigh,Width :Byte;
  24.           END;
  25.   PImage = ^Image;
  26.  
  27.   {Прямоугольник}
  28.   Rect = RECORD
  29.           left,top,right,bottom :Byte;
  30.   END;
  31.   {Окно}
  32.   TWindow = RECORD
  33.              Title    : String[78];
  34.              WinRect  : Rect;
  35.              OutPut   : Rect;
  36.              FrameAttr,
  37.              TextAttr : Byte;
  38.              Visible  : Boolean;
  39.              Back     : PImage;
  40.   END;
  41.   PWindow = ^TWindow;
  42.  
  43. CONST
  44.   {Прямоугольник экрана}
  45.   ScreenRect:Rect = (left:1; top:1; right:80 ;bottom:25);
  46.   {Флаг глобальных координат (т.е. сущестует ли
  47.                            в данный момент контекст окна)}
  48.   GlobalOut :Boolean = TRUE;
  49.  
  50. VAR
  51.   CurWindow    :PWindow; {Указатель на тек.окно}
  52.   CursorOn     :Boolean; {Флаг зажженого курсора}
  53.   ScreenWindow :PWindow; {Окно для экрана по умолчанию (см. инициализацию)}
  54.  
  55. {ВЫВОД}
  56. {Вызов процедуры Window для параметра-прямоугольника}
  57. PROCEDURE WindowRect(r:Rect);
  58. {Пишет строку, учитывая систему координат и цвет}
  59. PROCEDURE WriteString(X,Y:Byte; Str:String; Attr:Byte);
  60. {Пишет строку, центрируя и обрезая/перенося ее }
  61. PROCEDURE CenterString(row:Byte; Str:String; Split:Boolean; Attr:Byte);
  62. {Пишет строку вертикально}
  63. PROCEDURE WriteColumn(col,row:Byte; Str:String; Attr:Byte);
  64. {Заполняет прямоугольник ук. символом и цветом}
  65. PROCEDURE FillRect(r:Rect; Ch:Char; Attr:Byte);
  66.  
  67. {Считывает прямоугольник с экрана}
  68. PROCEDURE ReadImage(var r:Rect; var Im:PImage);
  69. {Пишет прямоугольник на экран}
  70. PROCEDURE WriteImage(x,y:Byte; Im:PImage);
  71.  
  72. {Включить/выключить курсор}
  73. PROCEDURE ShowCursor;
  74. PROCEDURE HideCursor;
  75. {Включить/выключить оконные координаты}
  76. PROCEDURE GlobalON;
  77. PROCEDURE GlobalOFF;
  78.  
  79. {ДОПОЛНИТЕЛЬНЫЕ ПРОЦЕДУРЫ}
  80. {Пишет символ с, начиная с (x,y) Count раз}
  81. PROCEDURE WriteChar(x,y:Byte; c:Char; Count:Word; Attr:Byte);
  82. {читает символ с экрана}
  83. PROCEDURE ReadChar(x,y:Byte; var C:ChAttr);
  84. {генерирует байт атрибута}
  85. FUNCTION  Attrib(TextCol,BackCol:Byte):Byte;
  86. {Присваивает Rect'у некое значение}
  87. PROCEDURE AssignRect(var R:Rect; x1,y1,x2,y2:Byte);
  88. {Создает структуру окна}
  89. PROCEDURE CreateWindow(var W:PWindow; Title:String; Win,Out:Rect;
  90.                                                 fa,ta:Byte; Vis:Boolean);
  91. {ОКНА}
  92. {Делает окно видимым}
  93. PROCEDURE ShowWindow(var W:PWindow);
  94. {Делает окно невидимым}
  95. PROCEDURE HideWindow(var W:PWindow);
  96. {Ликвидирует окно }
  97. PROCEDURE DisposeWindow(var W:PWindow);
  98.  
  99.  
  100. IMPLEMENTATION
  101.  
  102. {Вызов процедуры Window для параметра-прямоугольника}
  103. PROCEDURE WindowRect(r:Rect);
  104. BEGIN
  105.   Window(r.Left,r.Top,r.Right,r.Bottom);
  106. END;
  107.  
  108. {Пишет строку, учитывая систему координат и цвет}
  109. PROCEDURE WriteString(X,Y:Byte; Str:String; Attr:Byte);
  110. BEGIN
  111.   IF GlobalOut THEN WindowRect(ScreenRect)
  112.     ELSE WindowRect(CurWindow^.OutPut);
  113.   TextAttr :=Attr;
  114.   GotoXY(x,y);
  115.   Write(Str);
  116. END;
  117.  
  118. PROCEDURE CenterString(row:Byte; Str:String; Split:Boolean; Attr:Byte);
  119. VAR
  120.   RowWid,Beg,Len:Byte;
  121.   Str2 :String;
  122. BEGIN
  123.   IF Length(Str)=0 THEN Exit;
  124.   IF GlobalOut THEN WindowRect(ScreenRect)
  125.     ELSE WindowRect(CurWindow^.OutPut);
  126.  
  127.   TextAttr := Attr;
  128.   RowWid := Lo(WindMax)-Lo(WindMin)+1;
  129.   IF Length(Str) > RowWid THEN BEGIN
  130.      Len := RowWid - 4;
  131.      IF Split THEN BEGIN
  132.         Str2 := Copy(Str,Len+1,Ord(Str[0])-Len);
  133.         CenterString(row+1,Str2,Split,Attr);
  134.      END;
  135.      Str[0]:=Chr(Len);
  136.   END;
  137.   Beg := (RowWid - Length(Str)) div 2 + 1;
  138.   GotoXY(Beg,Row);
  139.   Write(Str);
  140. END;
  141.  
  142. PROCEDURE WriteColumn(col,row:Byte; Str:String; Attr:Byte);
  143. VAR
  144.   ColHigh,i:Byte;
  145. BEGIN
  146.   IF Length(Str)=0 THEN Exit;
  147.   IF GlobalOut THEN WindowRect(ScreenRect)
  148.     ELSE WindowRect(CurWindow^.OutPut);
  149.  
  150.   ColHigh := Hi(WindMax)-Row;
  151.   TextAttr := Attr;
  152.   IF Length(Str)-1 < ColHigh THEN ColHigh:=Length(Str)-1;
  153.   FOR I:=0 TO ColHigh DO BEGIN
  154.     GotoXY(col,row+I);
  155.     Write(Str[I+1]);
  156.   END;
  157. END;
  158.  
  159. PROCEDURE FillRect(r:Rect; Ch:Char; Attr:Byte);
  160. VAR i :Byte;
  161. BEGIN
  162.   IF NOT GlobalOut THEN BEGIN
  163.     Inc(r.Top,   CurWindow^.OutPut.Top-1);
  164.     Inc(r.Bottom,CurWindow^.OutPut.Top-1);
  165.     Inc(r.Left,  CurWindow^.OutPut.Left-1);
  166.     Inc(r.Right, CurWindow^.OutPut.Left-1);
  167.   END;
  168.   FOR I:=r.top TO r.Bottom DO
  169.      WriteChar(r.Left,I, Ch, r.Right-r.Left+1, Attr);
  170. END;
  171.  
  172. PROCEDURE WriteChar(x,y:Byte; c:Char; Count:Word; Attr:Byte);
  173. VAR r:Registers;
  174. BEGIN
  175.   IF GlobalOut THEN WindowRect(ScreenRect)
  176.     ELSE WindowRect(CurWindow^.OutPut);
  177.   GotoXY(x,y);
  178.   r.AH:=9;
  179.   r.BH:=0;
  180.   r.Al:=Ord(c);
  181.   r.BL:=Attr;
  182.   r.CX:=Count;
  183.   Intr($10,r);
  184. END;
  185.  
  186. PROCEDURE ReadChar(x,y:Byte; var C:ChAttr);
  187. VAR r:Registers;
  188. BEGIN
  189.   IF GlobalOut THEN WindowRect(ScreenRect)
  190.     ELSE WindowRect(CurWindow^.OutPut);
  191.   GotoXY(x,y);  {указываем место на экране}
  192.   r.AH:= 08;    {видеофункция 8}
  193.   r.BH:= 00;    {видеостраница 0}
  194.   Intr($10,r);
  195.   C.ASCII := Chr(r.AL);
  196.   C.Attr := r.AH;
  197. END;
  198.  
  199. PROCEDURE ReadImage(var r:Rect; var Im:PImage);
  200. VAR I,J :Byte;
  201. BEGIN
  202.   New(Im);
  203.   Im^.Heigh := r.Bottom - r.Top + 1;
  204.   Im^.Width := r.Right - r.Left + 1;
  205.   FOR I:= r.Left TO r.Right DO
  206.     FOR J:= r.Top TO r.Bottom DO
  207.       ReadChar(I,J,Im^.Chars[I - r.Left + 1, J - r.Top + 1]);
  208. END;
  209.  
  210. PROCEDURE WriteImage(x,y:Byte; Im:PImage);
  211. VAR I,J:Byte;
  212. BEGIN
  213.   IF Im = nil THEN Exit;
  214.   FOR I:= x TO Im^.Width + x - 1 DO
  215.     FOR J:= y TO Im^.Heigh + y - 1 DO
  216.       WriteChar(I,J,
  217.                 Im^.Chars[I-x+1,J-y+1].ASCII, 1,
  218.                 Im^.Chars[I-x+1,J-y+1].Attr);
  219. END;
  220.  
  221. PROCEDURE ShowCursor;
  222. VAR r:Registers;
  223. BEGIN
  224.   CursorOn:=TRUE;
  225.   r.AH:=01;
  226.   r.CH:=11;    {13 и 14 - стандартные значения для VGA }
  227.   r.CL:=12;    {Для EGA - заменить на 11 и 12}
  228.   Intr($10,r);
  229. END;
  230.  
  231. PROCEDURE HideCursor;
  232. VAR r:Registers;
  233. BEGIN
  234.   CursorON:=FALSE;
  235.   r.AH:=01;
  236.   r.CH:=$FF;    {все биты выключены - курсор не виден!}
  237.   r.CL:=$FF;
  238.   Intr($10,r);
  239. END;
  240.  
  241. PROCEDURE GlobalON;
  242. BEGIN GlobalOut := TRUE; END;
  243.  
  244. PROCEDURE GlobalOFF;
  245. BEGIN GlobalOut := FALSE; END;
  246.  
  247. FUNCTION  Attrib(TextCol,BackCol:Byte):Byte;
  248. BEGIN
  249.   Attrib := (TextCol AND $0F) + (BackCol AND $0F)*16;
  250. END;
  251.  
  252. PROCEDURE AssignRect(var R:Rect; x1,y1,x2,y2:Byte);
  253. BEGIN
  254.   R.Left  := x1;
  255.   R.Top   := y1;
  256.   R.Right := x2;
  257.   R.Bottom:= y2;
  258. END;
  259.  
  260. PROCEDURE WriteFrame(r:Rect;Attr:Byte);
  261. VAR I,J:Byte;
  262. BEGIN
  263.    FillRect(r,' ',Attr);
  264.    TextAttr:=Attr;
  265.    FOR I:=r.Top+1 TO r.Bottom-1 DO BEGIN
  266.      GotoXY(r.Left,I); Write('║');
  267.      GotoXY(r.Right,I); Write('║');
  268.    END;
  269.    FOR I:=r.Left+1 TO r.Right-1 DO BEGIN
  270.      GotoXY(I,r.Top); Write('═');
  271.      GotoXY(I,r.Bottom); Write('═');
  272.    END;
  273.    GotoXY(r.Left,r.Top);Write('╔');
  274.    GotoXY(r.Right,r.Top);Write('╗');
  275.    GotoXY(r.Left,r.Bottom);Write('╚');
  276.    GotoXY(r.Right,r.Bottom);Write('╝');
  277. END;
  278.  
  279. PROCEDURE WriteShadow(r:Rect);
  280. BEGIN
  281.    Inc(r.Top); Inc(r.Bottom);
  282.    Inc(r.Left); Inc(r.Right);
  283.    FillRect(r,' ',Attrib(DarkGray,DarkGray));
  284. END;
  285.  
  286. PROCEDURE ShowWindow(var W:PWindow);
  287. VAR r:Rect;
  288. BEGIN
  289.    IF W = nil THEN Exit;
  290.    IF W^.Visible THEN Exit;
  291.    GlobalON;
  292.    W^.Visible:=TRUE;
  293.  
  294.    r:=W^.WinRect; Inc(r.Right); Inc(r.Bottom);
  295.    ReadImage(r,W^.Back);
  296.  
  297.    WriteShadow(W^.WinRect);
  298.    WriteFrame(W^.WinRect,W^.FrameAttr);
  299.  
  300.    r:= W^.OutPut; W^.OutPut := W^.WinRect;
  301.    WindowRect(W^.WinRect);
  302.    CurWindow := W;
  303.    GlobalOFF;
  304.    CenterString(1,' '+W^.Title+' ',FALSE,W^.FrameAttr);
  305.    W^.OutPut := r;
  306.    CurWindow := W;
  307.    WindowRect(W^.OutPut);
  308. END;
  309.  
  310. PROCEDURE HideWindow(var W:PWindow);
  311. BEGIN
  312.   IF W<>CurWindow THEN Exit;
  313.   IF W^.Visible THEN W^.Visible:=FALSE ELSE Exit;
  314.   GlobalON;
  315.   CurWindow:=@ScreenWindow;
  316.   WriteImage(W^.WinRect.Left,W^.WinRect.Top,W^.Back);
  317. END;
  318.  
  319. PROCEDURE CreateWindow(var W:PWindow;Title:String; Win,Out:Rect; fa,ta:Byte; Vis:Boolean);
  320. BEGIN
  321.   IF W=nil THEN New(W);
  322.   W^.Title:= Title;
  323.   W^.WinRect:=Win;
  324.   W^.OutPut:=Out;
  325.   W^.FrameAttr:=fa;
  326.   W^.TextAttr:=ta;
  327.   W^.Visible := FALSE;
  328.   if Vis then ShowWindow(W);
  329. END;
  330.  
  331. PROCEDURE DisposeWindow(var W:PWindow);
  332. BEGIN
  333.   IF W = nil THEN Exit;
  334.   IF W^.Visible THEN HideWindow(W);
  335.   IF W^.Back<>nil THEN Dispose(W^.Back);
  336.   Dispose(W);
  337. END;
  338.  
  339. {Инициализация}
  340. BEGIN
  341.   ClrScr;
  342.   CheckSnow := TRUE;
  343.   CreateWindow(ScreenWindow,'',ScreenRect,ScreenRect,$0F,$0F,FAlse);
  344.   CurWindow := ScreenWindow;
  345.   HideCursor;
  346. END.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement