modes.inc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431
  1. {
  2. $Id$
  3. This file is part of the Free Pascal run time library.
  4. Copyright (c) 1993,99 by the Free Pascal development team
  5. This include implements video mode management.
  6. See the file COPYING.FPC, included in this distribution,
  7. for details about the copyright.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  11. **********************************************************************}
  12. {-----------------------------------------------------------------------}
  13. { Internal routines }
  14. {-----------------------------------------------------------------------}
  15. procedure addmode(mode: TModeInfo);
  16. {********************************************************}
  17. { Procedure AddMode() }
  18. {--------------------------------------------------------}
  19. { This routine adds <mode> to the list of recognized }
  20. { modes. Duplicates are allowed. }
  21. {********************************************************}
  22. var
  23. list: PModeInfo;
  24. newlst : PModeInfo;
  25. begin
  26. if not assigned(ModeList) then
  27. begin
  28. new(ModeList);
  29. move(mode, ModeList^, sizeof(Mode));
  30. end
  31. else
  32. begin
  33. list := ModeList;
  34. { go to the end of the list }
  35. while assigned(list^.next) do
  36. list:=list^.next;
  37. new(NewLst);
  38. list^.next := NewLst;
  39. move(mode, NewLst^, sizeof(Mode));
  40. end;
  41. end;
  42. procedure initmode(var mode: TModeInfo);
  43. {********************************************************}
  44. { Procedure InitMode() }
  45. {--------------------------------------------------------}
  46. { This routine initialized the mode to default values. }
  47. {********************************************************}
  48. begin
  49. FillChar(mode,sizeof(Mode),#0);
  50. end;
  51. function searchmode(ReqDriver : smallint; var reqmode: smallint): PModeInfo;
  52. {********************************************************}
  53. { Procedure SearchMode() }
  54. {--------------------------------------------------------}
  55. { This routine searches the list of recognized modes, }
  56. { and tries to find the <reqmode> in the <reqdriver> }
  57. { return nil if not found, otherwise returns the found }
  58. { structure. }
  59. { note: if reqmode = -32768, the first mode available }
  60. { for reqdriver is returned (JM) }
  61. {********************************************************}
  62. var
  63. lastDriver, lastMode: SmallInt;
  64. list, lastModeInfo: PModeInfo;
  65. begin
  66. {$ifdef logging}
  67. LogLn('Searching for driver '+strf(reqdriver)+' and mode '+strf(reqmode));
  68. {$endif logging}
  69. searchmode := nil;
  70. list := ModeList;
  71. If assigned(list) then
  72. lastModeInfo := list;
  73. { go to the end of the list }
  74. while assigned(list) do
  75. begin
  76. {$ifdef logging}
  77. Log('Found driver '+strf(list^.DriverNumber)+
  78. ' and mode $'+hexstr(list^.ModeNumber,4)+'... ');
  79. {$endif logging}
  80. if ((list^.DriverNumber = ReqDriver) and
  81. ((list^.ModeNumber = ReqMode) or
  82. { search for lowest mode }
  83. (reqMode = -32768))) or
  84. { search for highest mode }
  85. ((reqMode = -32767) and
  86. (lastModeInfo^.driverNumber = reqDriver) and
  87. ((list^.driverNumber <> lastModeInfo^.driverNumber) or
  88. not(assigned(list^.next)))) then
  89. begin
  90. {$ifdef logging}
  91. LogLn('Accepted!');
  92. {$endif logging}
  93. searchmode := list;
  94. If reqMode = -32768 then
  95. reqMode := list^.modeNumber
  96. else if reqMode = -32767 then
  97. begin
  98. reqMode := lastModeInfo^.modeNumber;
  99. searchMode := lastModeInfo;
  100. end;
  101. exit;
  102. end;
  103. {$ifdef logging}
  104. LogLn('Rejected.');
  105. {$endif logging}
  106. lastModeInfo := list;
  107. list:=list^.next;
  108. end;
  109. end;
  110. {-----------------------------------------------------------------------}
  111. { External routines }
  112. {-----------------------------------------------------------------------}
  113. function GetModeName(ModeNumber: smallint): string;
  114. {********************************************************}
  115. { Function GetModeName() }
  116. {--------------------------------------------------------}
  117. { Checks the known video list, and returns ModeName }
  118. { string. On error returns an empty string. }
  119. {********************************************************}
  120. var
  121. mode: PModeInfo;
  122. begin
  123. mode:=nil;
  124. GetModeName:='';
  125. { only search in the current driver modes ... }
  126. mode:=SearchMode(IntCurrentDriver,ModeNumber);
  127. if assigned(mode) then
  128. GetModeName:=Mode^.ModeName
  129. else
  130. _GraphResult := grInvalidMode;
  131. end;
  132. function GetGraphMode: smallint;
  133. begin
  134. GetGraphMode := IntCurrentMode;
  135. end;
  136. function GetMaxMode: word;
  137. { I know , i know, this routine is very slow, and it would }
  138. { be much easier to sort the linked list of possible modes }
  139. { instead of doing this, but I'm lazy!! And anyways, the }
  140. { speed of the routine here is not that important.... }
  141. var
  142. i: word;
  143. mode: PModeInfo;
  144. begin
  145. mode:=nil;
  146. i:=0;
  147. repeat
  148. inc(i);
  149. { mode 0 always exists... }
  150. { start search at 1.. }
  151. mode:=SearchMode(IntCurrentDriver,i);
  152. until not assigned(mode);
  153. GetMaxMode:=i;
  154. end;
  155. procedure GetModeRange(GraphDriver: smallint; var LoMode,
  156. HiMode: smallint);
  157. var
  158. mode : PModeInfo;
  159. begin
  160. {$ifdef logging}
  161. LogLn('GetModeRange : Enter ('+strf(GraphDriver)+')');
  162. {$endif}
  163. HiMode:=-1;
  164. mode := nil;
  165. { First search if the graphics driver is supported .. }
  166. { since mode zero is always supported.. if that driver }
  167. { is supported it should return something... }
  168. { not true, e.g. VESA doesn't have a mode 0. Changed so}
  169. { -32768 means "return lowest mode in second parameter }
  170. { also, under VESA some modes may not be supported }
  171. { (e.g. $108 here) while some with a higher number can }
  172. { be supported ($112 and onward), so I also added that }
  173. { -32767 means "return highest mode in second parameter}
  174. { This whole system should be overhauled though to work}
  175. { without such hacks (JM) }
  176. loMode := -32768;
  177. mode := SearchMode(GraphDriver, loMode);
  178. { driver not supported...}
  179. if not assigned(mode) then
  180. begin
  181. loMode := -1;
  182. exit;
  183. end;
  184. {$ifdef logging}
  185. LogLn('GetModeRange : Mode 0 found');
  186. {$endif}
  187. { now it exists... find highest available mode... }
  188. hiMode := -32767;
  189. mode:=SearchMode(GraphDriver,hiMode);
  190. end;
  191. procedure SetGraphMode(mode: smallint);
  192. var
  193. modeinfo: PModeInfo;
  194. begin
  195. { check if the mode exists... }
  196. modeinfo := searchmode(IntcurrentDriver,mode);
  197. if not assigned(modeinfo) then
  198. begin
  199. {$ifdef logging}
  200. LogLn('Mode setting failed in setgraphmode pos 1');
  201. {$endif logging}
  202. _GraphResult := grInvalidMode;
  203. exit;
  204. end;
  205. { reset all hooks...}
  206. DefaultHooks;
  207. { arccall not reset - tested against VGA BGI driver }
  208. { Setup all hooks if none, keep old defaults...}
  209. { required hooks - returns error if no hooks to these }
  210. { routines. }
  211. if assigned(modeinfo^.DirectPutPixel) then
  212. DirectPutPixel := modeinfo^.DirectPutPixel
  213. else
  214. begin
  215. {$ifdef logging}
  216. LogLn('Mode setting failed in setgraphmode pos 2');
  217. {$endif logging}
  218. _Graphresult := grInvalidMode;
  219. exit;
  220. end;
  221. if assigned(modeinfo^.PutPixel) then
  222. PutPixel := modeinfo^.PutPixel
  223. else
  224. begin
  225. {$ifdef logging}
  226. LogLn('Mode setting failed in setgraphmode pos 3');
  227. {$endif logging}
  228. _Graphresult := grInvalidMode;
  229. exit;
  230. end;
  231. if assigned(modeinfo^.GetPixel) then
  232. GetPixel := modeinfo^.GetPixel
  233. else
  234. begin
  235. {$ifdef logging}
  236. LogLn('Mode setting failed in setgraphmode pos 4');
  237. {$endif logging}
  238. _Graphresult := grInvalidMode;
  239. exit;
  240. end;
  241. if assigned(modeinfo^.SetRGBPalette) then
  242. SetRGBPalette := modeinfo^.SetRGBPalette
  243. else
  244. begin
  245. {$ifdef logging}
  246. LogLn('Mode setting failed in setgraphmode pos 5');
  247. {$endif logging}
  248. _Graphresult := grInvalidMode;
  249. exit;
  250. end;
  251. if assigned(modeinfo^.GetRGBPalette) then
  252. GetRGBPalette := modeinfo^.GetRGBPalette
  253. else
  254. begin
  255. {$ifdef logging}
  256. LogLn('Mode setting failed in setgraphmode pos 6');
  257. {$endif logging}
  258. _Graphresult := grInvalidMode;
  259. exit;
  260. end;
  261. { optional hooks. }
  262. if assigned(modeinfo^.ClearViewPort) then
  263. ClearViewPort := modeinfo^.ClearViewPort;
  264. if assigned(modeinfo^.PutImage) then
  265. PutImage := modeinfo^.PutImage;
  266. if assigned(modeinfo^.GetImage) then
  267. GetImage := modeinfo^.GetImage;
  268. if assigned(modeinfo^.ImageSize) then
  269. ImageSize := modeinfo^.ImageSize;
  270. if assigned(modeinfo^.GetScanLine) then
  271. GetScanLine := modeinfo^.GetScanLine;
  272. if assigned(modeinfo^.Line) then
  273. Line := modeinfo^.Line;
  274. if assigned(modeinfo^.InternalEllipse) then
  275. InternalEllipse := modeinfo^.InternalEllipse;
  276. if assigned(modeinfo^.PatternLine) then
  277. PatternLine := modeinfo^.PatternLine;
  278. if assigned(modeinfo^.HLine) then
  279. Hline := modeinfo^.Hline;
  280. if assigned(modeinfo^.Vline) then
  281. VLine := modeinfo^.VLine;
  282. if assigned(modeInfo^.SetVisualPage) then
  283. SetVisualPage := modeInfo^.SetVisualPage;
  284. if assigned(modeInfo^.SetActivePage) then
  285. SetActivePage := modeInfo^.SetActivePage;
  286. IntCurrentMode := modeinfo^.ModeNumber;
  287. IntCurrentDriver := modeinfo^.DriverNumber;
  288. XAspect := modeinfo^.XAspect;
  289. YAspect := modeinfo^.YAspect;
  290. MaxX := modeinfo^.MaxX;
  291. MaxY := modeinfo^.MaxY;
  292. HardwarePages := modeInfo^.HardwarePages;
  293. MaxColor := modeinfo^.MaxColor;
  294. PaletteSize := modeinfo^.PaletteSize;
  295. { is this a direct color mode? }
  296. DirectColor := modeinfo^.DirectColor;
  297. { now actually initialize the video mode...}
  298. { check first if the routine exists }
  299. if not assigned(modeinfo^.InitMode) then
  300. begin
  301. {$ifdef logging}
  302. LogLn('Mode setting failed in setgraphmode pos 7');
  303. {$endif logging}
  304. _GraphResult := grInvalidMode;
  305. exit;
  306. end;
  307. modeinfo^.InitMode;
  308. if _GraphResult <> grOk then exit;
  309. isgraphmode := true;
  310. { It is very important that this call be made }
  311. { AFTER the other variables have been setup. }
  312. { Since it calls some routines which rely on }
  313. { those variables. }
  314. SetActivePage(0);
  315. SetVisualPage(0);
  316. GraphDefaults;
  317. SetViewPort(0,0,MaxX,MaxY,TRUE);
  318. end;
  319. procedure RestoreCrtMode;
  320. {********************************************************}
  321. { Procedure RestoreCRTMode() }
  322. {--------------------------------------------------------}
  323. { Returns to the video mode which was set before the }
  324. { InitGraph. Hardware state is set to the old values. }
  325. {--------------------------------------------------------}
  326. { NOTE: - }
  327. { - }
  328. {********************************************************}
  329. begin
  330. isgraphmode := false;
  331. RestoreVideoState;
  332. end;
  333. {
  334. $Log$
  335. Revision 1.16 1999-12-21 17:42:18 jonas
  336. * changed vesa.inc do it doesn't try to use linear modes anymore (doesn't work
  337. yet!!)
  338. * fixed mode detection so the low modenumber of a driver doesn't have to be zero
  339. anymore (so VESA autodetection now works)
  340. Revision 1.15 1999/12/20 11:22:36 peter
  341. * integer -> smallint to overcome -S2 switch needed for ggi version
  342. Revision 1.14 1999/12/04 21:20:04 michael
  343. + Additional logging
  344. Revision 1.13 1999/11/28 16:13:55 jonas
  345. * corrected misplacement of call to initvars in initgraph
  346. + some extra debugging commands (for -dlogging) in the mode functions
  347. Revision 1.12 1999/09/28 13:56:31 jonas
  348. * reordered some local variables (first 4 byte vars, then 2 byte vars
  349. etc)
  350. * font data is now disposed in exitproc, exitproc is now called
  351. GraphExitProc (was CleanModes) and resides in graph.pp instead of in
  352. modes.inc
  353. Revision 1.11 1999/09/26 13:31:07 jonas
  354. * changed name of modeinfo variable to vesamodeinfo and fixed
  355. associated errors (fillchar(modeinfo,sizeof(tmodeinfo),#0) instead
  356. of sizeof(TVesamodeinfo) etc)
  357. * changed several sizeof(type) to sizeof(varname) to avoid similar
  358. errors in the future
  359. Revision 1.10 1999/09/24 22:52:39 jonas
  360. * optimized patternline a bit (always use hline when possible)
  361. * isgraphmode stuff cleanup
  362. * vesainfo.modelist now gets disposed in cleanmode instead of in
  363. closegraph (required moving of some declarations from vesa.inc to
  364. new vesah.inc)
  365. * queryadapter gets no longer called from initgraph (is called from
  366. initialization of graph unit)
  367. * bugfix for notput in 32k and 64k vesa modes
  368. * a div replaced by / in fillpoly
  369. Revision 1.9 1999/09/22 13:13:36 jonas
  370. * renamed text.inc -> gtext.inc to avoid conflict with system unit
  371. * fixed textwidth
  372. * isgraphmode now gets properly updated, so mode restoring works
  373. again
  374. Revision 1.8 1999/09/18 22:21:11 jonas
  375. + hlinevesa256 and vlinevesa256
  376. + support for not/xor/or/andput in vesamodes with 32k/64k colors
  377. * lots of changes to avoid warnings under FPC
  378. Revision 1.7 1999/07/12 13:27:14 jonas
  379. + added Log and Id tags
  380. * added first FPC support, only VGA works to some extend for now
  381. * use -dasmgraph to use assembler routines, otherwise Pascal
  382. equivalents are used
  383. * use -dsupportVESA to support VESA (crashes under FPC for now)
  384. * only dispose vesainfo at closegrph if a vesa card was detected
  385. * changed int32 to longint (int32 is not declared under FPC)
  386. * changed the declaration of almost every procedure in graph.inc to
  387. "far;" becquse otherwise you can't assign them to procvars under TP
  388. real mode (but unexplainable "data segnment too large" errors prevent
  389. it from working under real mode anyway)
  390. }