graph.pp 28 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993-98 by Florian Klaempf & Gernot Tenchio
  5. members of the Free Pascal development team.
  6. Graph unit for BP7 compatible RTL
  7. See the file COPYING.FPC, included in this distribution,
  8. for details about the copyright.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. **********************************************************************}
  13. unit GRAPH;
  14. { there are some problems with ranges in this file !! (PM) }
  15. {$R-}
  16. {$Q-}
  17. { $DEFINE DEBUG}
  18. {$I os.inc}
  19. {$ifdef DEBUG}
  20. {$define TEST_24BPP}
  21. {$define Test_Linear}
  22. {$endif DEBUG}
  23. { Output to AT&T for as }
  24. {$OUTPUT_FORMAT AS}
  25. { Use the direct assembler parser }
  26. {$ASMMODE DIRECT}
  27. { Don't use smartlinking, because of the direct assembler that is used }
  28. {$SMARTLINK OFF}
  29. interface
  30. uses go32,mmx;
  31. {$I GLOBAL.PPI}
  32. {$I STDCOLOR.PPI}
  33. procedure CloseGraph;
  34. function GraphResult : Integer;
  35. procedure InitGraph(var GraphDriver:Integer;var GraphMode:Integer;const PathToDriver:String);
  36. procedure SetGraphMode(GraphMode : integer);
  37. procedure GraphDefaults;
  38. procedure RestoreCRTMode;
  39. procedure SetGraphBufSize(BufSize : longint);
  40. function RegisterBGIdriver(driver : pointer) : integer;
  41. function InstallUserDriver(const DriverFileName : string;AutoDetectPtr : pointer) : integer;
  42. function GetDriverName: String;
  43. function GetModeName(Mode:Integer):String;
  44. function GetGraphMode:Integer;
  45. procedure GetAspectRatio(var _Xasp,_Yasp : word);
  46. procedure SetAspectRatio(_Xasp,_Yasp : word);
  47. function GraphErrorMsg(ErrorCode: Integer): string;
  48. function GetMaxMode : Integer;
  49. function GetMaxX : Integer;
  50. function GetMaxY : Integer;
  51. function GetX : Integer;
  52. function GetY : Integer;
  53. procedure Bar(x1,y1,x2,y2 : Integer);
  54. procedure bar3D(x1, y1, x2, y2 : integer;depth : word;top : boolean);
  55. procedure GetViewSettings(var viewport : ViewPortType);
  56. function GetNumberOfPages : word;
  57. procedure SetActivePage(page : word);
  58. function GetActivePage : word;
  59. procedure SetVisualPage(page : word);
  60. function GetVisualPage : word;
  61. procedure SetWriteMode(WriteMode : integer);
  62. procedure SetViewPort(x1,y1,x2,y2 : integer;clip : boolean);
  63. procedure Cleardevice;
  64. procedure ClearViewport;
  65. procedure Rectangle(x1,y1,x2,y2 : integer);
  66. { PIXEL.PPI }
  67. function GetPixel(x,y : integer):longint;
  68. procedure PutPixel(x,y : integer; Colour: longint);
  69. { LINE.PPI }
  70. procedure Line(x1,y1,x2,y2 : integer);
  71. procedure LineTo(x,y : integer);
  72. procedure LineRel(dx,dy : integer);
  73. procedure MoveTo(x,y : integer);
  74. procedure MoveRel(dx,dy : integer);
  75. procedure GetLineSettings(var LineInfo : LineSettingsType);
  76. procedure SetLineStyle(LineStyle : word;pattern : word;thickness : word);
  77. procedure DrawPoly(points : word;var polypoints);
  78. { PALETTE.PPI }
  79. procedure GetRGBPalette(ColorNum:byte; var RedValue,GreenValue,BlueValue:byte);
  80. procedure SetRGBPalette(ColorNum,RedValue,GreenValue,BlueValue:byte);
  81. procedure SetAllPalette(var Palette : PaletteType);
  82. procedure GetPalette(var Palette : PaletteType);
  83. procedure SetPalette(ColorNum:word;Color:byte);
  84. { ELLIPSE.PPI }
  85. procedure FillEllipse(x,y:Integer;XRadius,YRadius:Word);
  86. procedure Circle(x,y:Integer;Radius:Word);
  87. procedure Ellipse(x,y,alpha,beta:Integer;XRad,YRad:word);
  88. procedure Sector(X,Y,alpha,beta:integer;XRadius,YRadius: Word);
  89. { ARC.PPI }
  90. procedure Arc(x,y,alpha,beta:Integer;Radius:Word);
  91. procedure GetArcCoords(var ArcCoords:ArcCoordsType);
  92. procedure PieSlice(X,Y,alpha,beta:integer;Radius: Word);
  93. { COLORS.PPI }
  94. function GetBkColor : longint;
  95. function GetColor : longint;
  96. function GetMaxColor : longint;
  97. procedure SetColor(Color : longint);
  98. procedure SetBkColor(Color : longint);
  99. { FILL.PPI }
  100. procedure FloodFill(x,y:integer; Border:longint);
  101. procedure GetFillSettings(var FillInfo : FillSettingsType);
  102. procedure GetFillPattern(var FillPattern : FillPatternType);
  103. procedure SetFillStyle(pattern : word;color : longint);
  104. procedure SetFillPattern(pattern : FillPatternType;color : longint);
  105. { just dummy not implemented yet }
  106. procedure FillPoly(points : word;var polypoints);
  107. { IMAGE.PPI }
  108. function ImageSize(x1,y1,x2,y2 : integer) : longint;
  109. procedure GetImage(x1,y1,x2,y2 : integer;var BitMap);
  110. procedure PutImage(x,y : integer;var BitMap;BitBlt : word);
  111. { TEXT.PPI }
  112. procedure GetTextSettings(var TextInfo : TextSettingsType);
  113. procedure OutText(const TextString : string);
  114. procedure OutTextXY(x,y : integer;const TextString : string);
  115. procedure OutText(const Charakter : char);
  116. procedure OutTextXY(x,y : integer;const Charakter : char);
  117. procedure SetTextJustify(horiz,vert : word);
  118. procedure SetTextStyle(Font, Direction : word; CharSize : word);
  119. procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
  120. function TextHeight(const TextString : string) : word;
  121. function TextWidth(const TextString : string) : word;
  122. function RegisterBGIfont(font : pointer) : integer;
  123. function InstallUserFont(const FontFileName : string) : integer;
  124. { extended non Borland-compatible }
  125. { TRIANGLE.PPI }
  126. procedure FillTriangle(A,B,C:Pointtype);
  127. { to compare colors on different resolutions }
  128. function ColorsEqual(c1,c2 : longint) : boolean;
  129. { this will return true if the two colors will appear
  130. equal in the current video mode }
  131. procedure WaitRetrace;
  132. {$ifdef debug}
  133. procedure pixel(offset:longint);
  134. function Convert(color:longint):longint;
  135. function UnConvert(color:longint):longint;
  136. function SetVESADisplayStart(PageNum : word;x,y : integer):Boolean;
  137. {$endif debug}
  138. {$ifdef Test_linear}
  139. const
  140. UseLinear : boolean = false;
  141. (* Bug was due to alignment problem in VesaInfoBlock !!
  142. { the two below are the settings the work for ATI 3D Rage Pro !! }
  143. switch_physical_address : boolean = true;*)
  144. {$endif Test_linear}
  145. {$I MODES.PPI}
  146. implementation
  147. {$ASMMODE DIRECT}
  148. type
  149. PString=^String;
  150. PInteger=^integer;
  151. PWord=^word;
  152. PLong=^longint;
  153. VgaInfoBlock = record
  154. VESASignature: array[1..4]of Char;
  155. VESAloVersion: Byte;
  156. VESAhiVersion: Byte;
  157. OEMStringPtr : longint;
  158. Capabilities : longint;
  159. VideoModePtr : longint;
  160. TotalMem : word;
  161. { VESA 2.0 }
  162. OEMversion : word;
  163. VendorPtr : longint;
  164. ProductPtr : longint;
  165. RevisionPtr : longint;
  166. filler : Array[1..478]of Byte;
  167. end;
  168. VesaInfoBlock=record
  169. ModeAttributes : word; { pos 0 }
  170. WinAAttributes : byte; { pos 2 }
  171. WinBAttributes : byte; { pos 3 }
  172. WinGranularity : word; { pos 4 }
  173. WinSize : word; { pos 6 }
  174. segWINA : word; { pos 8 }
  175. segWINB : word; { pos $A }
  176. RealWinFuncPtr : longint; { pos $C }
  177. BPL : word; { pos $10 }
  178. { VESA 1.2 }
  179. XResolution : word; { pos $12 }
  180. YResolution : word; { pos $14 }
  181. XCharSize : byte; { pos $16 }
  182. YCharSize : byte; { pos $17 }
  183. MumberOfPlanes : byte; { pos $18 }
  184. BitsPerPixel : byte; { pos $19 }
  185. NumberOfBanks : byte; { pos $1A }
  186. MemoryModel : byte; { pos $1B }
  187. BankSize : byte; { pos $1C }
  188. NumberOfPages : byte; { pos $1D }
  189. reserved : byte; { pos $1E }
  190. rm_size : byte; { pos $1F }
  191. rf_pos : byte; { pos $20 }
  192. gm_size : byte; { pos $21 }
  193. gf_pos : byte; { pos $22 }
  194. bm_size : byte; { pos $23 }
  195. bf_pos : byte; { pos $24 }
  196. (* res_mask : word; { pos $25 }
  197. here there was an alignment problem !!
  198. with default alignment
  199. res_mask was shifted to $26
  200. and after PhysAddress to $2A !!! PM *)
  201. res_size : byte;
  202. res_pos : byte;
  203. DirectColorInfo: byte; { pos $27 }
  204. { VESA 2.0 }
  205. PhysAddress : longint; { pos $28 }
  206. OffscreenPtr : longint; { pos $2C }
  207. OffscreenMem : word; { pos $30 }
  208. reserved2 : Array[1..458]of Byte; { pos $32 }
  209. end;
  210. const
  211. CheckRange : Boolean=true;
  212. isVESA2 : Boolean=false;
  213. core : longint=$E0000000;
  214. var { X/Y Verhaeltnis des Bildschirm }
  215. AspectRatio : real;
  216. XAsp , YAsp : Word;
  217. { Zeilen & Spalten des aktuellen Graphikmoduses }
  218. _maxx,_maxy : longint;
  219. { Current color internal format (depending on bitsperpixel) }
  220. aktcolor : longint;
  221. { Current color RGB value }
  222. truecolor : longint;
  223. { Current background color internal format (depending on bitsperpixel) }
  224. aktbackcolor : longint;
  225. { Current background color RGB value }
  226. truebackcolor : longint;
  227. { used for fill }
  228. colormask : longint;
  229. { Videospeicherbereiche }
  230. wbuffer : ^byte;
  231. { Offset to current page }
  232. AktPageOffset : longint;
  233. AktPage : word;
  234. AktVisualPage : word;
  235. { these are not used !! PM }
  236. rbuffer,wrbuffer : ^byte;
  237. { aktueller Ausgabebereich }
  238. aktviewport : ViewPortType;
  239. aktscreen : ViewPortType;
  240. { der Graphikmodus, der beim Start gesetzt war }
  241. startmode : byte;
  242. { mode before RestoreCRTMode was called
  243. used by getGraphMode PM }
  244. oldCRTMode : integer;
  245. InTempCRTMode : boolean;
  246. { Position des Graphikcursors }
  247. curx,cury : longint;
  248. { true, wenn die Routinen des Graphikpaketes verwendet werden d�rfen }
  249. isgraphmode : boolean;
  250. { Einstellung zum Linien zeichnen }
  251. aktlineinfo : LineSettingsType;
  252. { Fehlercode, wird von graphresult zur�ckgegeben }
  253. _graphresult : integer;
  254. { aktuell eingestellte F�llart }
  255. aktfillsettings : FillSettingsType;
  256. aktfillbkcolor : longint;
  257. { aktuelles F�llmuster }
  258. aktfillpattern : FillPatternType;
  259. { Schreibmodus }
  260. aktwritemode : word;
  261. { put background color around text }
  262. ClearText : boolean;
  263. { Schrifteinstellung }
  264. akttextinfo : TextSettingsType;
  265. { momentan gesetzte Textskalierungswerte }
  266. aktmultx,aktdivx,aktmulty,aktdivy : word;
  267. { Pfad zu den Fonts }
  268. bgipath : string;
  269. { Pointer auf Hilfsspeicher }
  270. buffermem : pointer;
  271. { momentane GrӇe des Buffer }
  272. buffersize : longint;
  273. { in diesem Puffer werden bei SetFillStyle bereits die Pattern in der }
  274. { zu verwendenden Farbe abgelegt }
  275. PatternBuffer : Array [0..63] of LongInt;
  276. X_Array : array [0..1280] of LongInt;
  277. Y_Array : array [0..1024] of LongInt;
  278. Sel,Seg : word;
  279. VGAInfo : VGAInfoBlock;
  280. VESAInfo : VESAInfoBlock;
  281. { Selectors for Protected Mode }
  282. seg_WRITE : word;
  283. seg_READ : word;
  284. { linear Frame Buffer }
  285. LinearFrameBufferSupported : boolean;
  286. FrameBufferLinearAddress : longint;
  287. UseLinearFrameBuffer : Boolean;
  288. const
  289. EnableLinearFrameBuffer = $4000;
  290. { Registers for RealModeInterrupts in DPMI-Mode }
  291. var
  292. dregs : TRealRegs;
  293. { read and write bank are allways equal !! }
  294. A_Bank : longint;
  295. AW_window : longint;
  296. AR_Window : longint;
  297. same_window : boolean;
  298. const
  299. AWindow = 0;
  300. BWindow = 1;
  301. { Variables for Bankswitching }
  302. var
  303. BytesPerLine : longint;
  304. BytesPerPixel: Word;
  305. WinSize : longint; { Expample $0x00010000 . $0x00008000 }
  306. WinLoMask : longint; { $0x0000FFFF $0x00007FFF }
  307. WinLoMaskMinusPixelSize : longint; { $0x0000FFFF $0x00007FFF }
  308. WinShift : byte;
  309. GranShift : byte;
  310. Granular : longint;
  311. Granularity : longint;
  312. graphgetmemptr,
  313. graphfreememptr,
  314. bankswitchptr :pointer;
  315. isDPMI :Boolean;
  316. SwitchCS,SwitchIP : word;
  317. function ColorsEqual(c1,c2 : longint) : boolean;
  318. Begin
  319. ColorsEqual:=((BytesPerPixel=1) and ((c1 and $FF)=(c2 and $FF))) or
  320. ((GetMaxColor=$7FFF) and ((c1 and $F8F8F8)=(c2 and $F8F8F8))) or
  321. ((GetMaxColor=$FFFF) and ((c1 and $F8FCF8)=(c2 and $F8FCF8))) or
  322. ((BytesPerPixel>2) and ((c1 and $FFFFFF)=(c2 and $FFFFFF)));
  323. End;
  324. function GraphErrorMsg(ErrorCode: Integer): string;
  325. Begin
  326. GraphErrorMsg:='';
  327. case ErrorCode of
  328. grOk,grFileNotFound,grInvalidDriver: exit;
  329. grNoInitGraph: GraphErrorMsg:='Graphics driver not installed';
  330. grNotDetected: GraphErrorMsg:='Graphics hardware not detected';
  331. grNoLoadMem,grNoScanMem,grNoFloodMem: GraphErrorMsg := 'Not enough memory for graphics';
  332. grNoFontMem: GraphErrorMsg := 'Not enough memory to load font';
  333. grFontNotFound: GraphErrorMsg:= 'Font file not found';
  334. grInvalidMode: GraphErrorMsg := 'Invalid graphics mode';
  335. grError: GraphErrorMsg:='Graphics error';
  336. grIoError: GraphErrorMsg:='Graphics I/O error';
  337. grInvalidFont,grInvalidFontNum: GraphErrorMsg := 'Invalid font';
  338. grInvalidVersion: GraphErrorMsg:='Invalid driver version';
  339. end;
  340. end;
  341. procedure Oh_Kacke(ErrString:String);
  342. begin
  343. CloseGraph;
  344. writeln('Error in Unit VESA: ',ErrString);
  345. halt;
  346. end;
  347. {$I MOVE.PPI}
  348. {$I IBM.PPI}
  349. procedure WaitRetrace;
  350. begin
  351. asm
  352. cli
  353. movw $0x03Da,%dx
  354. .LWaitNotHSyncLoop:
  355. inb %dx,%al
  356. testb $0x8,%al
  357. jnz .LWaitNotHSyncLoop
  358. .LWaitHSyncLoop:
  359. inb %dx,%al
  360. testb $0x8,%al
  361. jz .LWaitHSyncLoop
  362. sti
  363. end;
  364. end;
  365. (* Unused, commented 20/11/98 PM
  366. procedure getmem(var p : pointer;size : longint);
  367. begin
  368. asm
  369. pushl 12(%ebp)
  370. pushl 8(%ebp)
  371. movl _GRAPHGETMEMPTR,%eax
  372. call %eax
  373. end;
  374. end;
  375. procedure freemem(var p : pointer;size : longint);
  376. begin
  377. asm
  378. pushl 12(%ebp)
  379. pushl 8(%ebp)
  380. movl _GRAPHFREEMEMPTR,%eax
  381. call %eax
  382. end;
  383. end; *)
  384. {$I COLORS.PPI}
  385. procedure graphdefaults;
  386. begin
  387. _graphresult:=grOk;
  388. if not isgraphmode then
  389. begin
  390. _graphresult:=grnoinitgraph;
  391. exit;
  392. end;
  393. { Linientyp }
  394. aktlineinfo.linestyle:=solidln;
  395. aktlineinfo.thickness:=normwidth;
  396. { std colors }
  397. setstdcolors;
  398. { Zeichenfarbe }
  399. setcolor(white);
  400. setbkcolor(black);
  401. { F�llmuster }
  402. setfillstyle(solidfill,white);
  403. { necessary to load patternbuffer !! (PM)
  404. aktfillsettings.color:=white;
  405. aktfillsettings.pattern:=solidfill; }
  406. { Viewport setzen }
  407. aktviewport.clip:=true;
  408. aktviewport.x1:=0;
  409. aktviewport.y1:=0;
  410. aktviewport.x2:=_maxx-1;
  411. aktviewport.y2:=_maxy-1;
  412. aktscreen:=aktviewport;
  413. { normaler Schreibmodus }
  414. setwritemode(normalput);
  415. { Schriftart einstellen }
  416. akttextinfo.font:=DefaultFont;
  417. akttextinfo.direction:=HorizDir;
  418. akttextinfo.charsize:=1;
  419. akttextinfo.horiz:=LeftText;
  420. akttextinfo.vert:=TopText;
  421. { VergrӇerungsfaktoren}
  422. XAsp:=10000; YAsp:=10000;
  423. aspectratio:=1;
  424. end;
  425. { ############################################################### }
  426. { ################# Ende der internen Routinen ################ }
  427. { ############################################################### }
  428. {$I PALETTE.PPI}
  429. {$I PIXEL.PPI}
  430. {$I LINE.PPI}
  431. {$I ELLIPSE.PPI}
  432. {$I TRIANGLE.PPI}
  433. {$I ARC.PPI}
  434. {$I IMAGE.PPI}
  435. {$I TEXT.PPI}
  436. {$I FILL.PPI}
  437. function GetDrivername:String;
  438. begin
  439. if not isgraphmode then
  440. begin
  441. _graphresult:=grNoInitGraph;
  442. Exit;
  443. end;
  444. GetDriverName:=('internal VESA-Driver');
  445. end;
  446. function GetModeName(Mode:Integer):String;
  447. var s1,s2,s3:string;
  448. begin
  449. if not isgraphmode then
  450. begin
  451. _graphresult:=grNoInitGraph;
  452. Exit;
  453. end;
  454. str(_maxx,s1);
  455. str(_maxy,s2);
  456. str(getmaxcolor+1,s3);
  457. GetModeName:=('VESA '+s1+'x'+s2+'x'+s3);
  458. end;
  459. function GetGraphMode:Integer;
  460. begin
  461. if InTempCRTMode then
  462. begin
  463. GetGraphMode:=oldCRTMode;
  464. exit;
  465. end;
  466. if not isgraphmode then
  467. begin
  468. _graphresult:=grNoInitGraph;
  469. GetGraphMode:=grNoInitGraph;
  470. Exit;
  471. end;
  472. GetGraphMode:=GetVesaMode;
  473. end;
  474. procedure ClearViewport;
  475. var bank1,bank2,diff,c:longint;
  476. ofs1,ofs2 :longint;
  477. y : integer;
  478. storewritemode : word;
  479. begin
  480. if not isgraphmode then
  481. begin
  482. _graphresult:=grNoInitGraph;
  483. Exit;
  484. end;
  485. c:=aktcolor;
  486. aktcolor:=aktbackcolor;
  487. storewritemode:=aktwritemode;
  488. aktwritemode:=normalput;
  489. ofs1:=Y_ARRAY[aktviewport.y1] + X_ARRAY[aktviewport.x1];
  490. ofs2:=Y_ARRAY[aktviewport.y1] + X_ARRAY[aktviewport.x2];
  491. for y:=aktviewport.y1 to aktviewport.y2 do
  492. begin
  493. bank1:=ofs1 shr winshift;
  494. bank2:=ofs2 shr winshift;
  495. if bank1 <> A_BANK then
  496. begin
  497. Switchbank(bank1);
  498. end;
  499. if bank1 <> bank2 then
  500. begin
  501. diff:=((bank2 shl winshift)-ofs1) div BytesPerPixel;
  502. horizontalline(aktviewport.x1, aktviewport.x1+diff-1, y);
  503. Switchbank(bank2);
  504. horizontalline(aktviewport.x1+diff, aktviewport.x2, y);
  505. end else horizontalline(aktviewport.x1, aktviewport.x2, y);
  506. ofs1:=ofs1 + BytesPerLine;
  507. ofs2:=ofs2 + BytesPerLine;
  508. end;
  509. aktwritemode:=storewritemode;
  510. aktcolor:=c;
  511. end;
  512. procedure GetAspectRatio(var _Xasp,_Yasp : word);
  513. begin
  514. _graphresult:=grOk;
  515. if not isgraphmode then
  516. begin
  517. _graphresult:=grnoinitgraph;
  518. exit;
  519. end;
  520. _XAsp:=XAsp; _YAsp:=YAsp;
  521. end;
  522. procedure SetAspectRatio(_Xasp, _Yasp : word);
  523. begin
  524. _graphresult:=grOk;
  525. if not isgraphmode then
  526. begin
  527. _graphresult:=grnoinitgraph;
  528. exit;
  529. end;
  530. Xasp:=_XAsp; YAsp:=_YAsp;
  531. end;
  532. procedure ClearDevice;
  533. var Viewport:ViewportType;
  534. begin
  535. if not isgraphmode then
  536. begin
  537. _graphresult:=grNoInitGraph;
  538. Exit;
  539. end;
  540. Viewport:=aktviewport;
  541. SetViewport(0,0,_maxx-1,_maxy-1,Clipon);
  542. ClearViewport;
  543. aktviewport:=viewport;
  544. end;
  545. procedure Rectangle(x1,y1,x2,y2:integer);
  546. begin
  547. if not isgraphmode then
  548. begin
  549. _graphresult:=grNoInitGraph;
  550. Exit;
  551. end;
  552. Line(x1,y1,x2,y1);
  553. Line(x1,y1,x1,y2);
  554. Line(x2,y1,x2,y2);
  555. Line(x1,y2,x2,y2);
  556. end;
  557. procedure Bar(x1,y1,x2,y2:integer);
  558. var y : Integer;
  559. origcolor : longint;
  560. origlinesettings: Linesettingstype;
  561. begin
  562. if not isgraphmode then
  563. begin
  564. _graphresult:=grNoInitGraph;
  565. Exit;
  566. end;
  567. origlinesettings:=aktlineinfo;
  568. origcolor:=aktcolor;
  569. aktlineinfo.linestyle:=solidln;
  570. aktlineinfo.thickness:=normwidth;
  571. case aktfillsettings.pattern of
  572. emptyfill : begin
  573. aktcolor:=aktbackcolor;
  574. for y:=y1 to y2 do line(x1,y,x2,y);
  575. end;
  576. solidfill : begin
  577. aktcolor:=aktfillsettings.color;
  578. for y:=y1 to y2 do line(x1,y,x2,y);
  579. end;
  580. else for y:=y1 to y2 do patternline(x1,x2,y);
  581. end;
  582. aktcolor:=origcolor;
  583. aktlineinfo:=origlinesettings;
  584. end;
  585. procedure bar3D(x1, y1, x2, y2 : integer;depth : word;top : boolean);
  586. begin
  587. if not isgraphmode then
  588. begin
  589. _graphresult:=grNoInitGraph;
  590. Exit;
  591. end;
  592. Bar(x1,y1,x2,y2);
  593. Rectangle(x1,y1,x2,y2);
  594. if top then begin
  595. Moveto(x1,y1);
  596. Lineto(x1+depth,y1-depth);
  597. Lineto(x2+depth,y1-depth);
  598. Lineto(x2,y1);
  599. end;
  600. Moveto(x2+depth,y1-depth);
  601. Lineto(x2+depth,y2-depth);
  602. Lineto(x2,y2);
  603. end;
  604. procedure SetGraphBufSize(BufSize : longint);
  605. begin
  606. if assigned(buffermem) then
  607. freemem(buffermem,buffersize);
  608. getmem(buffermem,bufsize);
  609. if not assigned(buffermem) then
  610. buffersize:=0
  611. else buffersize:=bufsize;
  612. end;
  613. const
  614. { Vorgabegr”áe f�r Hilfsspeicher }
  615. bufferstandardsize = 64*8196; { 0,5 MB }
  616. procedure CloseGraph;
  617. begin
  618. if isgraphmode then
  619. begin
  620. SetVESAMode(startmode);
  621. { DoneVESA; only in exitproc !! PM }
  622. isgraphmode:=false;
  623. if assigned(buffermem) then
  624. freemem(buffermem,buffersize);
  625. buffermem:=nil;
  626. buffersize:=0;
  627. end;
  628. end;
  629. procedure SetArrays;
  630. var
  631. index:Integer;
  632. begin
  633. for index:=0 to VESAInfo.XResolution do
  634. X_Array[index]:=index * BytesPerPixel;
  635. for index:=0 to VESAInfo.YResolution do
  636. Y_Array[index]:=index * BytesPerLine + AktPageOffset;
  637. end;
  638. procedure InitGraph(var GraphDriver:Integer;var GraphMode:Integer;const PathToDriver:String);
  639. var i : Integer;
  640. begin
  641. { Pfad zu den Fonts }
  642. bgipath:=PathToDriver;
  643. if bgipath[length(bgipath)]<>'\' then
  644. bgipath:=bgipath+'\';
  645. if Graphdriver=detect then GraphMode:=GetMaxMode;
  646. { Standardfonts installieren }
  647. InstallUserFont('TRIP');
  648. InstallUserFont('LITT');
  649. InstallUserFont('SANS');
  650. InstallUserFont('GOTH');
  651. InstallUserFont('SCRI');
  652. InstallUserFont('SIMP');
  653. InstallUserFont('TSCR');
  654. InstallUserFont('LCOM');
  655. InstallUserFont('EURO');
  656. InstallUserFont('BOLD');
  657. GetVESAInfo(GraphMode);
  658. {$IFDEF DEBUG}
  659. {$I VESADEB.PPI}
  660. {$ENDIF}
  661. for i:=VESANumber downto 0 do
  662. if GraphMode=VESAModes[i] then break;
  663. { the modes can be refused due to the monitor ? }
  664. { that happens by me at home Pierre Muller }
  665. while i>=0 do begin
  666. isgraphmode:=SetVESAMode(GraphMode);
  667. if isgraphmode then begin
  668. GetVESAInfo(GraphMode);
  669. if UseLinearFrameBuffer then
  670. isgraphmode:=SetVESAMode(GraphMode or EnableLinearFrameBuffer);
  671. { set zero page }
  672. AktPageOffset:=0;
  673. SetActivePage(0);
  674. SetVisualPage(0);
  675. SetArrays;
  676. SetGraphBufSize(bufferstandardsize);
  677. graphdefaults;
  678. InTempCRTMode:=false;
  679. exit;
  680. end;
  681. dec(i);
  682. GraphMode:=VESAModes[i];
  683. end;
  684. _graphresult:=grInvalidMode
  685. end;
  686. procedure SetGraphMode(GraphMode:Integer);
  687. begin
  688. _graphresult:=grOk;
  689. if not isgraphmode and not InTempCRTMode then
  690. begin
  691. _graphresult:=grNoInitGraph;
  692. Exit;
  693. end;
  694. if GetVesaInfo(GraphMode) then
  695. begin
  696. isgraphmode:=SetVESAMode(GraphMode);
  697. if isgraphmode then
  698. begin
  699. if UseLinearFrameBuffer then
  700. isgraphmode:=SetVESAMode(GraphMode or EnableLinearFrameBuffer);
  701. { set zero page }
  702. AktPageOffset:=0;
  703. SetActivePage(0);
  704. SetVisualPage(0);
  705. SetArrays;
  706. graphdefaults;
  707. InTempCRTMode:=false;
  708. exit;
  709. end;
  710. end;
  711. _graphresult:=grInvalidMode;
  712. end;
  713. function RegisterBGIdriver(driver : pointer) : integer;
  714. begin
  715. RegisterBGIdriver:=grerror;
  716. end;
  717. function InstallUserDriver(const DriverFileName : string;AutoDetectPtr : pointer) : integer;
  718. begin
  719. installuserdriver:=grerror;
  720. end;
  721. function GetMaxMode:Integer;
  722. var i:Byte;
  723. begin
  724. for i:=VESANumber downto 0 do
  725. if GetVesaInfo(VESAModes[i]) then
  726. begin
  727. GetMaxMode:=VESAModes[i];
  728. Exit;
  729. end;
  730. end;
  731. function GetMaxX:Integer;
  732. begin
  733. if not isgraphmode then
  734. begin
  735. _graphresult:=grNoInitGraph;
  736. Exit;
  737. end;
  738. GetMaxX:=VESAInfo.XResolution-1;
  739. end;
  740. function GetMaxY:Integer;
  741. begin
  742. if not isgraphmode then
  743. begin
  744. _graphresult:=grNoInitGraph;
  745. Exit;
  746. end;
  747. GetMaxY:=VESAInfo.YResolution-1;
  748. end;
  749. function GetX : integer;
  750. begin
  751. _graphresult:=grOk;
  752. if not isgraphmode then
  753. begin
  754. _graphresult:=grNoInitGraph;
  755. Exit;
  756. end;
  757. GetX:=curx;
  758. end;
  759. function GetY : integer;
  760. begin
  761. _graphresult:=grOk;
  762. if not isgraphmode then
  763. begin
  764. _graphresult:=grNoInitGraph;
  765. Exit;
  766. end;
  767. GetY:=cury;
  768. end;
  769. procedure SetViewPort(x1,y1,x2,y2 : integer;clip : boolean);
  770. begin
  771. _graphresult:=grOk;
  772. if not isgraphmode then
  773. begin
  774. _graphresult:=grNoInitGraph;
  775. exit;
  776. end;
  777. { Daten �berpr�fen }
  778. if (x1<0) or (y1<0) or (x2>=_maxx) or (y2>=_maxy) then exit;
  779. aktviewport.x1:=x1;
  780. aktviewport.y1:=y1;
  781. aktviewport.x2:=x2;
  782. aktviewport.y2:=y2;
  783. aktviewport.clip:=clip;
  784. end;
  785. procedure GetViewSettings(var viewport : ViewPortType);
  786. begin
  787. _graphresult:=grOk;
  788. if not isgraphmode then
  789. begin
  790. _graphresult:=grNoInitGraph;
  791. exit;
  792. end;
  793. viewport:=aktviewport;
  794. end;
  795. { mehrere Bildschirmseiten werden nicht unterst�tzt }
  796. { Dummy aus Kompatibilit„tsgr�nden }
  797. procedure SetVisualPage(page : word);
  798. begin
  799. _graphresult:=grOk;
  800. if not isgraphmode then
  801. begin
  802. _graphresult:=grNoInitGraph;;
  803. exit;
  804. end
  805. else if (Page<VESAInfo.NumberOfPages) and (AktVisualPage<>Page) then
  806. begin
  807. SetVESADisplayStart(Page,0,0);
  808. {SetDisplayPage(Page);}
  809. AktVisualPage:=Page;
  810. end;
  811. end;
  812. function GetVisualPage : word;
  813. begin
  814. GetVisualPage:=AktVisualPage;
  815. end;
  816. function GetActivePage : word;
  817. begin
  818. GetActivePage:=AktPage;
  819. end;
  820. { mehrere Bildschirmseiten werden nicht unterst�tzt }
  821. { Dummy aus Kompatibilit„tsgr�nden }
  822. procedure SetActivePage(page : word);
  823. begin
  824. _graphresult:=grOk;
  825. if not isgraphmode then
  826. begin
  827. _graphresult:=grNoInitGraph;;
  828. exit;
  829. end
  830. else if (Page<VESAInfo.NumberOfPages) and (Page<>AktPage) then
  831. begin
  832. AktPageOffset:=Page*BytesPerLine*_maxy;
  833. AktPage:=Page;
  834. SetArrays;
  835. end;
  836. end;
  837. function GetNumberOfPages : word;
  838. begin
  839. GetNumberOfPages:=VESAInfo.NumberOfPages;
  840. end;
  841. procedure SetWriteMode(WriteMode : integer);
  842. begin
  843. _graphresult:=grOk;
  844. if not isgraphmode then
  845. begin
  846. _graphresult:=grNoInitGraph;;
  847. exit;
  848. end;
  849. if ((writemode and 7)<>xorput) and ((writemode and 7)<>normalput) then
  850. begin
  851. _graphresult:=grError;
  852. exit;
  853. end;
  854. aktwritemode:=(writemode and 7);
  855. if (writemode and BackPut)<>0 then
  856. ClearText:=true
  857. else
  858. ClearText:=false;
  859. end;
  860. function GraphResult:Integer;
  861. begin
  862. GraphResult:=_graphresult;
  863. end;
  864. procedure RestoreCRTMode;
  865. begin
  866. if not isgraphmode then
  867. begin
  868. _graphresult:=grNoInitGraph;
  869. Exit;
  870. end;
  871. OldCRTMode:=GetGraphMode;
  872. InTempCRTMode:=true;
  873. SetVESAMode(startmode);
  874. isgraphmode:=false;
  875. end;
  876. var PrevExitProc : pointer;
  877. procedure GraphExit;
  878. begin
  879. ExitProc:=PrevExitProc;
  880. CloseGraph;
  881. DoneVesa; { frees the ldt descriptors seg_read and seg_write !! }
  882. end;
  883. begin
  884. InitVESA;
  885. if not DetectVESA then
  886. Oh_Kacke('VESA-BIOS not found...');
  887. startmode:=GetVESAMode;
  888. PrevExitProc:=ExitProc;
  889. ExitProc:=@GraphExit;
  890. bankswitchptr:=@switchbank;
  891. GraphGetMemPtr:[email protected];
  892. GraphFreeMemPtr:[email protected];
  893. Getdefaultfont;
  894. if not isDPMI then begin
  895. wrbuffer:=pointer($D0000000);
  896. rbuffer:=pointer($D0200000);
  897. wbuffer:=pointer($D0200000);
  898. end else begin
  899. wrbuffer:=pointer($0);
  900. rbuffer:=pointer($0);
  901. wbuffer:=pointer($0);
  902. end;
  903. AktPageOffset:=0;
  904. AktPage:=0;
  905. AktVisualPage:=0;
  906. end.
  907. {
  908. $Log$
  909. Revision 1.3 1999-03-02 13:56:34 peter
  910. * use ATT assembler in profile
  911. * use AS output in graph
  912. Revision 1.2 1999/02/01 13:19:01 pierre
  913. * getgraphmode returns -1 if not in graphic mode
  914. Revision 1.1 1998/12/21 13:07:03 peter
  915. * use -FE
  916. Revision 1.15 1998/12/15 22:42:50 peter
  917. * removed temp symbols
  918. Revision 1.14 1998/11/25 22:59:23 pierre
  919. * fillpoly works
  920. Revision 1.13 1998/11/25 13:04:43 pierre
  921. + added multi page support
  922. Revision 1.12 1998/11/23 10:04:16 pierre
  923. * pieslice and sector work now !!
  924. * bugs in text writing removed
  925. + scaling for defaultfont added
  926. + VertDir for default font added
  927. * RestoreCRTMode corrected
  928. Revision 1.11 1998/11/20 18:42:04 pierre
  929. * many bugs related to floodfill and ellipse fixed
  930. Revision 1.10 1998/11/20 10:16:01 pierre
  931. * Found out the LinerFrameBuffer problem
  932. Was an alignment problem in VesaInfoBlock (see graph.pp file)
  933. Compile with -dDEBUG and answer 'y' to 'Use Linear ?' to test
  934. Revision 1.9 1998/11/19 15:09:33 pierre
  935. * several bugfixes for sector/ellipse/floodfill
  936. + graphic driver mode const in interface G800x600x256...
  937. + added backput mode as in linux graph.pp
  938. (clears the background of textoutput)
  939. Revision 1.8 1998/11/19 09:48:45 pierre
  940. + added some functions missing like sector ellipse getarccoords
  941. (the filling of sector and ellipse is still buggy
  942. I use floodfill but sometimes the starting point
  943. is outside !!)
  944. * fixed a bug in floodfill for patterns
  945. (still has problems !!)
  946. Revision 1.7 1998/11/18 09:31:29 pierre
  947. * changed color scheme
  948. all colors are in RGB format if more than 256 colors
  949. + added 24 and 32 bits per pixel mode
  950. (compile with -dDEBUG)
  951. 24 bit mode with banked still as problems on pixels across
  952. the bank boundary, but works in LinearFrameBufferMode
  953. Look at install/demo/nmandel.pp
  954. Revision 1.6 1998/10/22 09:44:57 pierre
  955. * PatternBuffer was not set on entry !!
  956. Revision 1.5 1998/09/16 16:47:25 peter
  957. * merged fixes
  958. Revision 1.4.2.1 1998/09/16 16:15:41 peter
  959. * no smartlinking!
  960. Revision 1.4 1998/05/31 14:18:14 peter
  961. * force att or direct assembling
  962. * cleanup of some files
  963. Revision 1.3 1998/05/22 00:39:23 peter
  964. * go32v1, go32v2 recompiles with the new objects
  965. * remake3 works again with go32v2
  966. - removed some "optimizes" from daniel which were wrong
  967. }