home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / t / tvg103_s.zip / TVGRAPH.PAS < prev    next >
Pascal/Delphi Source File  |  1992-07-29  |  22KB  |  844 lines

  1.  
  2. {$A-,B-,D+,E+,F+,G-,I+,L+,N-,O-,R-,S-,V-,X-}
  3. {$M 16384,0,655360}
  4. {$DEFINE DEMO}
  5. unit TvGraph;
  6.  
  7. (* Include this unit before any other TVision unit and the program will *)
  8. (* Work entirely in graphics mode and look identical ( although slower) *)
  9. (* to the original text display. Using this in conjunction with a       *)
  10. (* companion unit TVGOBJ, will allow you to do graphics using the full  *)
  11. (* capability of TURBO VISION Menus,Dialog boxes etc.                   *)
  12.  
  13. interface
  14.  
  15. uses
  16.   Drivers,Objects,Views;
  17.  
  18. const
  19.   GraphXMax=10000;
  20.   GraphYMax=07500;
  21.   smEGA = $0010;
  22.   smVGA = $0012;
  23.   smGraphAutoDetect=$00FF;   (* Autodetect *)
  24.   wrmOVERWRITE = 0;
  25.   wrmAND = 1;
  26.   wrmOR = 2;
  27.   wrmXOR = 3;
  28.  
  29. var
  30.   GraphMouseLoc:TPoint; (* Graphics location of Mouse *)
  31.  
  32.  
  33. type
  34.  PGRect=^GRect;
  35.  GRect=Trect;
  36.  
  37.  PGPoint=^GPoint;
  38.  GPoint=TPoint;
  39.  
  40. function NextGraphId:byte;
  41. procedure UseGraphId(b:byte);
  42. procedure ReleaseGraphId(b:byte);
  43. procedure TextToGraphics(T:TRect;var G:Grect);
  44. procedure RawDrawLine(X1,Y1,X2,Y2:integer;Color:word);
  45. procedure DrawLine(X1,Y1,X2,Y2:integer;Color:word);
  46. function ISin(X:integer):integer;
  47. function ICos(X:integer):integer;
  48.  
  49. implementation
  50.  
  51. const
  52.   (********************************************************************)
  53.   (*                                                                  *)
  54.   (*    CRITICAL - WARNING LOOK AT THIS CONSTANT - VERSION DEPENDANT  *)
  55.   (*                                                                  *)
  56.   (********************************************************************)
  57.   OfsFromInit=$261-$222;
  58.   (* Offset between where the Views.Tview.Init procedure is and where *)
  59.   (* the code starts for the Checksnow = TRUE code                    *)
  60.   (* This value is absolutely critical and may change between         *)
  61.   (* Turbovision releases  WATCH OUT CRITICAL                         *)
  62.  
  63.   CurrentGraphWindow:byte=1;
  64.   CurrentLineStyle:word=$FFFF;
  65.                         (* Current Line style in 1=line 0=no line       *)
  66.   CurrentLineWriteMode:byte=$00;
  67.                         (* Current Write mode for lines                 *)
  68.   SineTable:array[0..180] of integer=
  69.        (0,9,18,27,36,45,54,63,71,80,89,98,107,116,125,134,143,151,160,169,178,
  70.         187,195,204,213,222,230,239,248,256,265,274,282,291,299,308,316,325,333,
  71.         342,350,359,367,375,384,392,400,408,416,425,433,441,449,457,465,473,481,
  72.         489,496,504,512,520,527,535,543,550,558,565,573,580,587,595,602,609,616,
  73.         623,630,637,644,651,658,665,672,679,685,692,698,705,711,718,724,730,737,
  74.         743,749,755,761,767,773,779,784,790,796,801,807,812,818,823,828,834,839,
  75.         844,849,854,859,864,868,873,878,882,887,891,896,900,904,908,912,916,920,
  76.         924,928,932,935,939,943,946,949,953,956,959,962,965,968,971,974,977,979,
  77.         982,984,987,989,991,994,996,998,1000,1002,1003,1005,1007,1008,1010,1011,
  78.         1013,1014,1015,1016,1017,1018,1019,1020,1021,1022,1022,1023,1023,1023,
  79.         1024,1024,1024,1024);
  80.  
  81.  
  82. type
  83. {$IFDEF DEMO}
  84.   Vector = record X1,Y1,X2,Y2:word; end;
  85. {$ENDIF}
  86.   ABitFont = array[0..255] of array[0..15] of byte;
  87.   (* Store upto 32 line high font *)
  88.   PAbitFont = ^ABitFont;
  89.   (* The pointer to a copy of the currently in use font *)
  90.   PtrRec = record O,S:word; end;  (* used to separate Ofs and Seg     *)
  91. var
  92.   (* All the hardware dependant routines called indirectly *)
  93.   Do_INIT_X:procedure;
  94.   Do_DONE_X:Procedure;
  95.   TVGraphCursorOn_X,
  96.   TVGraphCursorOff_X,
  97.   TVUpdateCursor_X,
  98.   Do_GraphMOV_X,
  99.   NewJmp_GraphMOV_X:pointer;
  100.   Draw_Any_Line_X:procedure (X1,Y1,X2,Y2:word;Color:byte);
  101.   Draw_Horiz_Line_X:procedure (X1,X2,Y:word;Color:byte);
  102.   Draw_Vert_Line_X:procedure (X,Y1,Y2:word;Color:byte);
  103.  
  104.   P1,P2:Pointer;        (* General pointers used for copies             *)
  105.   BytesPerLine:word;    (* Bytes per line in graphics mode              *)
  106.   VideoBufferSeg:word;  (* Video Segment for display                    *)
  107.   GTVEventRoutine:PtrRec;
  108.                         (* Address of TVision mouse event handler       *)
  109.   GTVEventMask:word;    (* Mask as passed by call to handler install    *)
  110.   OldINT33h,OldINT10h:Pointer;
  111.                         (* Old pointers to call for INT 33 and INT 10   *)
  112.   Int33h:Pointer absolute $0000:$00CC;
  113.                         (* INT 33h actual address                       *)
  114.   Int10h:Pointer absolute $0000:$0040;
  115.                         (* INT 10h actual address                       *)
  116.   RomFont:PABitFont absolute $0000:$010C;
  117.                         (* Address of current FONT                      *)
  118.   ColorList:word;       (* Pointer to List of color masks in EGA memory *)
  119.   Count:word;           (* Counts down the number of char's in GRAPHMOV *)
  120.   DestOfs:word;         (* Destination in EGA of the current mask       *)
  121.   TextSource:PtrRec;    (* Source for next Ch/Attr pair                 *)
  122.   TextDest:word;        (* Normal destination for text 0..screen size   *)
  123.   SaveJump:word;        (* Save jump location for GraphMov              *)
  124.   TvGraphLoc,TvGraphCursor:word;
  125.                         (* Store current text x,y and top/bottom cursor *)
  126.   TvViziFlag:byte;      (* Toggles ON=FF and OFF=00 for cursor          *)
  127.   FontTable:ABitFont;   (* In Memory font table                         *)
  128.   PtrFontTable:PABitFont;(* Pointer to In Memory font table             *)
  129.   GraphWriteAvail:array[0..4095] of byte;
  130.   (* one byte for each text position on the screen, 0=text screen and   *)
  131.   (* a number 1-254 representing distinct graphics windows and 255      *)
  132.   (* represents the mouse cursor positions                              *)
  133.   GraphIdSet:set of byte;
  134.   CharWidth,CharHeight:byte;
  135.                         (* Width and Height in text mode                *)
  136.   GraphWidth,GraphHeight:word;
  137.                         (* Width and height in graphics                 *)
  138. {$IFDEF DEMO}
  139.   DWString:array[1..35] of word; (* Used for text writing *)
  140.  
  141. const
  142.   TVGraphAd:array[1..29] of Vector=
  143.   ((X1:220;Y1:125;X2:240;Y2:125), (*T2*)
  144.    (X1:230;Y1:125;X2:230;Y2:150),
  145.    (X1:245;Y1:125;X2:255;Y2:150), (*V2*)
  146.    (X1:255;Y1:150;X2:265;Y2:125),
  147.    (X1:290;Y1:125;X2:280;Y2:125), (*G7*)
  148.    (X1:280;Y1:125;X2:270;Y2:130),
  149.    (X1:270;Y1:130;X2:270;Y2:145),
  150.    (X1:270;Y1:145;X2:280;Y2:150),
  151.    (X1:280;Y1:150;X2:290;Y2:150),
  152.    (X1:290;Y1:150;X2:290;Y2:140),
  153.    (X1:290;Y1:140;X2:280;Y2:140),
  154.    (X1:295;Y1:150;X2:295;Y2:125), (*R6*)
  155.    (X1:295;Y1:125;X2:305;Y2:125),
  156.    (X1:305;Y1:125;X2:315;Y2:130),
  157.    (X1:315;Y1:130;X2:315;Y2:135),
  158.    (X1:315;Y1:135;X2:295;Y2:140),
  159.    (X1:305;Y1:140;X2:315;Y2:150),
  160.    (X1:320;Y1:150;X2:320;Y2:135), (*A5*)
  161.    (X1:320;Y1:135;X2:330;Y2:125),
  162.    (X1:330;Y1:125;X2:340;Y2:135),
  163.    (X1:340;Y1:135;X2:340;Y2:150),
  164.    (X1:320;Y1:140;X2:340;Y2:140),
  165.    (X1:345;Y1:150;X2:345;Y2:125), (*P4*)
  166.    (X1:345;Y1:125;X2:365;Y2:125),
  167.    (X1:365;Y1:125;X2:365;Y2:140),
  168.    (X1:365;Y1:140;X2:345;Y2:140),
  169.    (X1:370;Y1:125;X2:370;Y2:150), (*H3*)
  170.    (X1:390;Y1:125;X2:390;Y2:150),
  171.    (X1:370;Y1:137;X2:390;Y2:137));
  172.   AdvertText:array[1..9] of string[35]=
  173.   ('      Graphics in TURBOVISION      ',
  174.    '         Copyright 1991            ',
  175.    'C.L.Burke of MindWare QLD Australia',
  176.    'R.A.Morris of KHIRON QLD Australia ',
  177.    '         The Wizards of Oz         ',
  178.    '          AND COMING SOON          ',
  179.    '   GWHIZ graphics objects in the   ',
  180.    '      spirit of TurboVision        ',
  181.    '    PRESS ANY KEY TO CONTINUE      ');
  182. {$ENDIF}
  183.  
  184. procedure DisableInterrupts; inline($FA);
  185. procedure EnableInterrupts; inline($FB);
  186.  
  187. procedure MouseCursorOff;assembler;
  188. asm
  189.  mov ax,0002h
  190.  cli
  191.  pushf
  192.  call [OldInt33h]
  193.  sti
  194. end;
  195.  
  196. procedure MouseCursorOn;assembler;
  197. asm
  198.  mov ax,0001h
  199.  cli
  200.  pushf
  201.  call [OldInt33h]
  202.  sti
  203. end;
  204.  
  205. {$I TVGRAPH.IN0}        (* Display Identify routines *)
  206. {$I TVGRAPH.IN1}        (* Display Specific routines *)
  207.  
  208.  
  209. {$IFDEF DEMO}
  210.  
  211. procedure RawWriteString(X,Y:Word;S:String);
  212. const
  213.  NormTextColor=$1A00;
  214. var
  215.  ScrLoc:word;
  216.  Cnt:word;
  217. begin
  218.  ScrLoc:=Y*160+X*2;
  219.  for Cnt:=1 to 35 do
  220.    DWString[Cnt]:=NormTextColor+ord(S[Cnt]);
  221.  asm
  222.   mov si,offset DWString
  223.   mov ax,seg DWString
  224.   mov di,[ScrLoc]
  225.   push ds
  226.   mov ds,ax
  227.   mov cx,35
  228.   call [Do_GraphMOV_X]
  229.   pop ds
  230.  end;
  231. end;
  232.  
  233. procedure Advertisement;
  234. const
  235.  BorderColor=15;
  236.  BackgroundColor=1;
  237.  VectorColor=14;
  238. var
  239.  XL,XH,YL,YH:word;
  240.  Cnt:word;
  241. begin
  242.  for cnt:=0 to 3 do
  243.   RawDrawLine(170-Cnt,100-Cnt,470+Cnt,100-Cnt,BorderColor);
  244.  for cnt:=0 to 3 do
  245.   RawDrawLine(470+Cnt,100-Cnt,470+Cnt,300+Cnt,BorderColor);
  246.  for cnt:=0 to 3 do
  247.   RawDrawLine(470+Cnt,300+Cnt,170-Cnt,300+Cnt,BorderColor);
  248.  for cnt:=0 to 3 do
  249.   RawDrawLine(170-Cnt,300+Cnt,170-Cnt,100-Cnt,BorderColor);
  250.  for Cnt:=101 to 299 do
  251.   RawDrawLine(171,Cnt,469,Cnt,BackGroundColor);
  252.  for Cnt:=1 to 29 do
  253.  With TvGraphAd[Cnt] do
  254.  begin
  255.   RawDrawLine(X1+9,Y1-10,X2+9,Y2-10,VectorColor);
  256.   RawDrawLine(X1+10,Y1-11,X2+10,Y2-11,VectorColor);
  257.   RawDrawLine(X1+10,Y1-10,X2+10,Y2-10,VectorColor);
  258.   RawDrawLine(X1+10,Y1-9,X2+10,Y2-9,VectorColor);
  259.   RawDrawLine(X1+11,Y1-10,X2+11,Y2-10,VectorColor);
  260.  end;
  261.  XL:=(175 div Charwidth)+1;
  262.  XH:=(465 div Charwidth)-1;
  263.  YL:=(140 div CharHeight);
  264.  YH:=(295 div CharHeight)-1;
  265.  for cnt:=1 to 9 do
  266.    RawWriteString(XL+1,YL+cnt,AdvertText[cnt]);
  267.  asm
  268.   mov ax,0
  269.   int 16h
  270.  end;
  271. end;
  272. {$ENDIF}
  273.  
  274. function NextGraphId:byte;
  275. var
  276.  I:byte;
  277.  Found:boolean;
  278. begin
  279.  I:=0;
  280.  repeat
  281.   Inc(I);
  282.   Found:=not (I in GraphIdSet);
  283.  until (I=254) or found;
  284.  NextGraphId:=I;
  285. end;
  286.  
  287. procedure UseGraphId(b:byte);
  288. begin
  289.  GraphIdSet:=GraphIdSet+[b];
  290.  CurrentGraphWindow:=b;
  291. end;
  292.  
  293. procedure ReleaseGraphId(b:byte);
  294. begin
  295.  GraphIdSet:=GraphIdSet-[b];
  296. end;
  297.  
  298. function GraphIdAt(X,Y:integer):byte;
  299. begin
  300.  X:=X div CharWidth;
  301.  Y:=Y div CharHeight;
  302.  GraphIdAt:=GraphWriteAvail[Y*ScreenWidth+X]
  303. end;
  304.  
  305. function ISin(X:integer):integer; assembler;
  306. asm
  307. (* X is number of 16ths of a degree *)
  308.      mov bx,OFFSET SineTable
  309.      mov ch,1         (* sign of result *)
  310.      mov si,[X]
  311.      test si,08000h
  312.      jz @L01
  313.      neg ch           (* negative SIN(-A) = -SIN(A) *)
  314.      neg si           (* Angle is positive *)
  315. @L01:cmp si,16*360
  316.      jl  @L02
  317.      sub si,16*360
  318.      jmp @L01
  319. @L02:cmp si,16*180    (* Angle is 0..359 *)
  320.      jl  @L03
  321.      neg ch
  322.      sub si,16*180    (* angle is 0..180 *)
  323. @L03:cmp si,16*90
  324.      jle @L04
  325.      neg si
  326.      add si,16*180
  327. @L04:mov cl,3         (* angle is 0..90 *)
  328.      shr si,cl
  329.      shl si,1
  330.      mov ax,[BX+SI]
  331.      test ch,080h
  332.      jz @L05
  333.      neg ax
  334. @L05:
  335. end;
  336.  
  337. function ICos(X:integer):integer;
  338. begin
  339.  ICos:=ISin(X+90*16);
  340. end;
  341.  
  342. procedure ClearWindow(Bounds:TRect;Color:word);
  343. var
  344.  Cnt:word;
  345. begin
  346.  for Cnt:=Bounds.A.Y to Bounds.B.Y do
  347.    RawDrawLine(Bounds.A.X,Cnt,Bounds.B.X,Cnt,Color);
  348. end;
  349.  
  350. procedure New_INT10h; assembler;
  351. asm
  352. (* Replace INT10 to emulate cursor stuff *)
  353.  push ds
  354.  pushf
  355.  
  356.  push si
  357.  mov si,seg @Data
  358.  mov ds,si
  359.  pop si
  360.  
  361.  cmp ah,1
  362.  jne @NOT1
  363.  call [TvGraphCursorOff_X]
  364.  test cx,0E0E0h
  365.  jnz @NoTrans
  366.  push ax
  367.  mov ah,[CharHeight]
  368.  dec ah                 (* AH= max cursor line *)
  369.  sub ah,cl              (* Difference between max line and request e.g. -2*)
  370.  cmp cl,7
  371.  jle @CL_OK
  372.  add cl,ah
  373. @CL_OK:
  374.  cmp ch,7
  375.  jle @CH_OK
  376.  add ch,ah
  377. @CH_OK:
  378.  pop ax
  379. @NoTrans:
  380.  mov [TvGraphCursor],cx
  381.  call [TvUpdateCursor_X]
  382.  jmp @DOIRET
  383. @NOT1:
  384.  cmp ah,2
  385.  jne @NOT2
  386.  call [TvGraphCursorOff_X]
  387.  mov [TvGraphLoc],dx
  388.  call [TvUpdateCursor_X]
  389.  jmp @DOIRET
  390. @NOT2:
  391.  cmp ah,3
  392.  jne @NOT3
  393.  mov dx,[TvGraphLoc]
  394.  mov cx,[TvGraphCursor]
  395.  jmp @DOIRET
  396. @NOT3:
  397.  call [OldInt10h]
  398.  pop ds
  399.  iret
  400. @DOIRET:
  401.  popf
  402.  pop ds
  403.  iret
  404. end;
  405.  
  406. procedure New_EventHandler;assembler;
  407. asm
  408. (* Old event handler divides mouse co-ordinates by 8 all the time   *)
  409. (* New Event handler which multiplies by 8 and divides by character *)
  410. (* and then calls the old event handler resulting in the correct    *)
  411. (* division.                                                        *)
  412.     push si
  413.     push ax
  414.     push bx
  415.     mov si,seg @Data
  416.     mov ds,si
  417.  
  418.     mov [GraphMouseLoc.X],cx
  419.     mov [GraphMouseLoc.Y],dx
  420.  
  421.     mov ax,8
  422.     mul dx             (* DX:AX = 8*Y *)
  423.     xor bh,bh
  424.     mov bl,[CharHeight]
  425.     div bx          (* DX:AX = 8*Y/CharHeight *)
  426.     mov dx,ax          (* DX = 8*Y/CharHeight *)
  427.  
  428.     push dx
  429.  
  430.     mov ax,8       (* X co-ord *)
  431.     mul cx         (* AX = X*8 *)
  432.     xor bh,bh
  433.     mov bl,[CharWidth]
  434.     div bx         (* AX = X*8/CharWidth *)
  435.     mov cx,ax      (* X <- X*8/CharWidth *)
  436.  
  437.     pop dx
  438.  
  439.     pop bx
  440.     pop ax
  441.     pop si
  442.     jmp dword [GTVEventRoutine]
  443. end;
  444.  
  445. procedure New_INT33h; assembler;
  446. (* New mouse interrupt handler to fix graphics *)
  447. asm
  448.  cli
  449.  push ds
  450.  pushf                        (* call interrupt will call as INT 33h *)
  451.  push ax
  452.  mov ax,seg @Data
  453.  mov ds,ax
  454.  pop ax
  455.  cmp ax,0ch
  456.  jz  @change1
  457.  call [OldInt33h]
  458.  pop ds
  459.  sti
  460.  iret
  461.  
  462. @Change1:   (* Intercept the change Event routine and save the values *)
  463.  mov [GTVEventMask],CX
  464.  mov cx,es
  465.  mov [GTVEventRoutine.S],Cx
  466.  mov [GTVEventRoutine.O],Dx
  467.  mov CX,[GTVEventMask]
  468.  mov dx,SEG New_EventHandler  (*our Event handler *)
  469.  mov es,dx
  470.  mov dx,OFFSET New_EventHandler
  471.  call [OldInt33h] (* has been intercepted *)
  472.  
  473.  pop ds
  474.  sti
  475.  iret
  476. end;
  477.  
  478. (* Turn off Events *)
  479. procedure ResetMouse; assembler;
  480. asm
  481.  mov ax,0
  482.  int 33h
  483.  ret
  484. end;
  485.  
  486. (* Normal text mode video routines *)
  487. procedure SetVidParams(var Smode,Cline:word);
  488. begin
  489.   asm
  490.     les bx,Smode
  491.     mov ax,es:[bx]
  492.     mov ah,0
  493.     int 10h
  494.     mov ah,1
  495.     les bx,Cline
  496.     mov cx,es:[bx]
  497.     int 10h
  498.   end;
  499. end;
  500.  
  501. procedure GetVidParams(var Smode,Cline:word);
  502. begin
  503.   asm
  504.     mov ah,0fh          (* Save video mode *)
  505.     int 10h
  506.     mov ah,0
  507.     les bx,Smode
  508.     mov es:[bx],ax
  509.     mov ah,03h
  510.     int 10h
  511.     les bx,Cline
  512.     mov es:[bx],cx
  513.   end;
  514. end;
  515.  
  516. (* Copy ROM font table to RAM *)
  517. procedure CopyROMfont;
  518. var
  519.   FontPtr:pointer;
  520.   Cnt:byte;
  521. begin
  522.   FontPtr:=RomFont;
  523.   for cnt:=0 to 255 do
  524.   begin
  525.    move(FontPtr^,FontTable[cnt],CharHeight); (* Insert New Jump for GRAPH_MOV *)
  526.    inc(longint(FontPtr),CharHeight);
  527.   end;
  528.   PtrFontTable:=@FontTable;
  529. end;
  530.  
  531. (* This function replaces the DoneVideo procedure command in Drivers *)
  532. procedure Do_DoneVideo;
  533. var
  534.  CLine,SMode:word;
  535. begin
  536.  Do_DONE_X;
  537.  DisableInterrupts;
  538.  Int33h:=OldInt33h;
  539.  Int10h:=OldInt10h;
  540.  EnableInterrupts;
  541.  SetVidParams(StartupMode,CursorLines);
  542. end;
  543.  
  544. (* This code is copied over start of the DoneVideo procedure in Drivers *)
  545. procedure NewJmp_DoneVideo; assembler;
  546. asm
  547.  jmp far ptr Do_DoneVideo (* 5 *)
  548. end;                    (*TOTAL 5 bytes*)
  549.  
  550. (* This function replaces the SetVideoMode procedure command in Drivers *)
  551. procedure Do_SetVideoMode(Mode:word);
  552. var
  553.   Driver:Vsystem;
  554. begin
  555.   Driver := WhatVsystem;
  556.   if hi(Mode)=$01 then HiresScreen:=TRUE;
  557.   Mode:=Mode and $FF;
  558.   if (Mode>$13) or
  559.     not (Driver in GraphScreenInfo[Mode].SuitableAdapters) or
  560.     (GraphScreenInfo[Mode].ScreenSeg= $0000) then
  561.    begin
  562.      case Driver of
  563.        Mono,Herc:Mode:=smMono;
  564.        EGA:Mode:=smEGA;
  565.        VGA:Mode:=smVGA;
  566.        else Mode:=smCO80;
  567.      end;
  568.    end;
  569.   if GraphScreenInfo[Mode].ScreenWriteType=_GRAPHICS then
  570.   begin
  571.     case Mode of
  572.       smEGA:Do_Set_EGAVGA;
  573.       smVGA:Do_Set_EGAVGA;
  574.     end;
  575.     ScreenMode:=Mode;
  576.     SetVidParams(ScreenMode,CursorLines);
  577.     P1:=@Views.Tview.Init;
  578.     dec(PtrRec(P1).O,OfsFromInit);
  579.     P2:=NewJmp_GraphMOV_X;
  580.     move(P2^,P1^,13); (* Insert New Jump for GRAPH_MOV *)
  581.     HiresScreen:=FALSE;
  582.     CharWidth:=8;
  583.     CharHeight:=Mem[$40:$85];
  584.     ScreenWidth:=GraphScreenInfo[Mode].Xres div CharWidth;
  585.     ScreenHeight:=GraphScreenInfo[Mode].YRes div CharHeight;
  586.     GraphWidth:=GraphScreenInfo[Mode].Xres;
  587.     GraphHeight:=GraphScreenInfo[Mode].YRes;
  588.     CheckSnow:=TRUE;
  589.     BytesPerLine:= ScreenWidth;
  590.     VideoBufferSeg:=GraphScreenInfo[Mode].ScreenSeg;
  591.     TvViziFlag:=0;
  592.     TvGraphLoc:=0;
  593.     TvGraphCursor:=$2000;
  594.     asm
  595.       call [TvUpdateCursor_X];
  596.     end;
  597.     ScreenBuffer:=Ptr(GraphScreenInfo[Mode].ScreenSeg,$0000);
  598.     Do_INIT_X;
  599.   end else
  600.   begin
  601.     Do_DONE_X;
  602.     SetVidParams(StartupMode,CursorLines);
  603.     writeln('That mode not supported in TVGRAPH yet ');
  604.     writeln;
  605.     halt(255);
  606.   end;
  607. end;
  608.  
  609. (* This code is copied over start of the SetVideoMode procedure in Drivers *)
  610. procedure NewJmp_SetVideoMode; assembler;
  611. asm
  612.  jmp far ptr Do_SetVideoMode (* 5 *)
  613. end;                    (*TOTAL 5 bytes*)
  614.  
  615.  
  616. (* This function replaces the InitVideo procedure command in Drivers *)
  617. procedure Do_InitVideo;
  618. begin
  619.   GetVidParams(StartupMode,CursorLines);
  620.   Do_SetVideoMode(smGraphAutoDetect);
  621.   ResetMouse;
  622. {  Do_SetVideoMode(smEGA);}
  623.   DisableInterrupts;
  624.   OldInt33h:=Int33h;
  625.   OldInt10h:=Int10h;
  626.   Int33h:=@New_Int33h;
  627.   Int10h:=@New_Int10h;
  628.   EnableInterrupts;
  629.   CopyROMFont;
  630. {$IFDEF DEMO}
  631.   fillchar(GraphWriteAvail,sizeof(GraphWriteAvail),#1);
  632.   AdVertisement;
  633. {$ENDIF}
  634.   fillchar(GraphWriteAvail,sizeof(GraphWriteAvail),#0);
  635. end;
  636.  
  637. (* This code is copied over start of the InitVideo procedure in Drivers *)
  638. procedure NewJmp_InitVideo; assembler;
  639. asm
  640.  jmp far ptr Do_InitVideo (* 5 *)
  641. end;                    (*TOTAL 5 bytes*)
  642.  
  643. function RegionOf(X,Y:integer;WX1,WY1,WX2,WY2:integer):byte; assembler;
  644. asm
  645.  xor ch,ch
  646.  mov ax,[X]
  647.  
  648.  cmp ax,[WX1]
  649.  jge @RO1
  650.  or ch,0001B
  651. @RO1:
  652.  cmp ax,[WX2]
  653.  jle @RO2
  654.  or ch,0100B
  655. @RO2:
  656.  mov ax,[Y]
  657.  cmp ax,[WY1]
  658.  jge @RO3
  659.  or ch,0010B
  660. @RO3:
  661.  cmp ax,[WY2]
  662.  jle @RO4
  663.  or ch,1000B
  664. @RO4:
  665.  mov al,ch
  666. end;
  667.  
  668.  
  669. procedure SwapInts(var A,B:integer);assembler;
  670. asm
  671.  push ds
  672.  les si,A
  673.  lds di,B
  674.  mov ax,es:[si]
  675.  xchg ax,[di]
  676.  mov es:[si],ax
  677.  pop ds
  678. end;
  679.  
  680. procedure SwapBytes(var A,B:byte);assembler;
  681. asm
  682.  push ds
  683.  les si,A
  684.  lds di,B
  685.  mov al,es:[si]
  686.  xchg al,[di]
  687.  mov es:[si],al
  688.  pop ds
  689. end;
  690.  
  691. procedure ClipPoint(var A1,B1:integer;A2,B2,L:integer);
  692. (* Applies the following formula for extending A1,B1 along *)
  693. (* a line such that B1=L                                   *)
  694. var
  695.  T0:longint;
  696.  T1,T2:integer;
  697. begin
  698.  T1:=A2-A1;
  699.  T2:=L-B1;
  700.  T0:=LongMul(T1,T2);
  701.  T1:=B2-B1;
  702.  if T1<>0 then
  703.    A1:=A1+LongDiv(T0,T1);
  704.  B1:=L;
  705. end;
  706.  
  707. function ClipLine(var X1,Y1,X2,Y2:integer;var R:TRect):boolean;
  708. var
  709.  Inside,Outside:boolean;
  710.  Ocu1,Ocu2:byte;
  711. begin
  712.  Ocu1:=RegionOf(X1,Y1,R.A.X,R.A.Y,R.B.X,R.B.Y);
  713.  Ocu2:=RegionOf(X2,Y2,R.A.X,R.A.Y,R.B.X,R.B.Y);
  714.  Inside:=((Ocu1 or Ocu2) = 0);
  715.  Outside:=((Ocu1 and Ocu2) <> 0);
  716.  
  717.  while not Inside and not Outside do
  718.  begin
  719.    if Ocu1=0 then
  720.    begin
  721.      SwapInts(X1,X2);
  722.      SwapInts(Y1,Y2);
  723.      SwapBytes(Ocu1,Ocu2);
  724.    end;
  725.  
  726.    if ((Ocu1 and $01)<>0) then
  727.      ClipPoint(Y1,X1,Y2,X2,R.A.X)
  728.    else if ((Ocu1 and $02)<>0) then
  729.      ClipPoint(X1,Y1,X2,Y2,R.A.Y)
  730.    else if ((Ocu1 and $04)<>0) then
  731.      ClipPoint(Y1,X1,Y2,X2,R.B.X)
  732.    else if ((Ocu1 and $08)<>0) then
  733.      ClipPoint(X1,Y1,X2,Y2,R.B.Y);
  734.  
  735.    Ocu1:=RegionOf(X1,Y1,R.A.X,R.A.Y,R.B.X,R.B.Y);
  736.    Ocu2:=RegionOf(X2,Y2,R.A.X,R.A.Y,R.B.X,R.B.Y);
  737.    Inside:=((Ocu1 or Ocu2) = 0);
  738.    Outside:=((Ocu1 and Ocu2) <> 0);
  739.  end;
  740.  ClipLine:=Inside;
  741. end;
  742.  
  743. procedure NoClipDrawLine(X1,Y1,X2,Y2:integer;Color:word);
  744. begin
  745.    if X1=X2 then
  746.       Draw_Vert_Line_X(X1,Y1,Y2,Color)
  747.    else if Y1=Y2 then
  748.       Draw_Horiz_Line_X(X1,X2,Y1,Color)
  749.    else Draw_Any_Line_X(X1,Y1,X2,Y2,Color);
  750. end;
  751.  
  752. procedure GlobalToPhysical(Var X,Y:integer);
  753. var
  754.  T:Longint;
  755. begin
  756.   T:=longmul(X,GraphWidth);
  757.   X:=longdiv(T,GraphXMax);
  758.   T:=longmul(Y,GraphHeight);
  759.   Y:=longdiv(T,GraphYMax);
  760. end;
  761.  
  762. procedure RawDrawLine(X1,Y1,X2,Y2:integer;Color:word);
  763. var
  764.  MR,R:TRect;
  765.  LineThruMouse:boolean;
  766.  X1M,X2M,Y1M,Y2M:integer;
  767.  (* MR is mouse rectangle, R is Window rectangle *)
  768. begin
  769.  R.Assign(0,0,GraphWidth-1,GraphHeight-1);
  770.  if ClipLine(X1,Y1,X2,Y2,R) then (* Line is visible *)
  771.  begin
  772.    with GraphMouseLoc do
  773.    begin
  774.      LineThruMouse:=(GraphIdAt(X-3,Y-3)=CurrentGraphWindow) or
  775.                     (GraphIdAt(X+16,Y-3)=CurrentGraphWindow) or
  776.                     (GraphIdAt(X-3,Y+16)=CurrentGraphWindow) or
  777.                     (GraphIdAt(X+16,Y+16)=CurrentGraphWindow);
  778.      MR.Assign(X-3,Y-3,X+16,Y+16);
  779.    end;
  780.    X1M:=X1;X2M:=X2;Y1M:=Y1;Y2M:=Y2;
  781.    if LineThruMouse then
  782.       LineThruMouse:=ClipLine(X1M,Y1M,X2M,Y2M,MR);
  783.  
  784.    if X1>X2 then
  785.    begin
  786.      SwapInts(X1,X2);
  787.      SwapInts(Y1,Y2);
  788.    end else if (X1=X2) and (Y1>Y2) then SwapInts(Y1,Y2);
  789.  
  790.    if LineThruMouse then
  791.      MouseCursorOff;
  792.    NoClipDrawLine(X1,Y1,X2,Y2,Color);
  793.    if LineThruMouse then
  794.      MouseCursorOn;
  795.  end;
  796. end;
  797.  
  798. procedure DrawLine(X1,Y1,X2,Y2:integer;Color:word);
  799. begin
  800.  GlobalToPhysical(X1,Y1);
  801.  GlobalToPhysical(X2,Y2);
  802.  RawDrawLine(X1,Y1,X2,Y2,Color);
  803. end;
  804.  
  805. procedure PhysicalToGlobal(Var P:GPoint);
  806. var
  807.  T:Longint;
  808. begin
  809.  with P do
  810.  begin
  811.    T:=longmul(X,GraphXMax);
  812.    X:=longdiv(T,GraphWidth);
  813.    T:=longmul(Y,GraphYMax);
  814.    Y:=longdiv(T,GraphHeight);
  815.  end;
  816. end;
  817.  
  818. procedure TextToGraphics(T:TRect;var G:GRect);
  819. begin
  820.  G.A.X:=T.A.X*CharWidth;
  821.  G.A.Y:=T.A.Y*CharHeight;
  822.  G.B.X:=T.B.X*CharWidth;
  823.  G.B.Y:=T.B.Y*CharHeight;
  824.  PhysicalToGlobal(GPoint(G.A));
  825.  PhysicalToGlobal(GPoint(G.B));
  826. end;
  827.  
  828. begin
  829.   (* overwrite the start of each of the main functions *)
  830.   P1:=@Drivers.InitVideo;
  831.   P2:=@NewJmp_InitVideo;
  832.   move(P2^,P1^,5);
  833.  
  834.   P1:=@Drivers.SetVideoMode;
  835.   P2:=@NewJmp_SetVideoMode;
  836.   move(P2^,P1^,5);
  837.  
  838.   P1:=@Drivers.DoneVideo;
  839.   P2:=@NewJmp_DoneVideo;
  840.   move(P2^,P1^,5);
  841.  
  842.   fillchar(graphidset,sizeof(graphidset),#0);
  843. end.
  844.