modes.inc 13 KB

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